KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > maven > lifecycle > DefaultLifecycleExecutor


1 package org.apache.maven.lifecycle;
2
3 /*
4  * Copyright 2001-2005 The Apache Software Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18
19 import org.apache.maven.BuildFailureException;
20 import org.apache.maven.artifact.handler.ArtifactHandler;
21 import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
22 import org.apache.maven.artifact.repository.ArtifactRepository;
23 import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
24 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
25 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
26 import org.apache.maven.execution.MavenSession;
27 import org.apache.maven.execution.ReactorManager;
28 import org.apache.maven.extension.ExtensionManager;
29 import org.apache.maven.lifecycle.mapping.LifecycleMapping;
30 import org.apache.maven.model.Extension;
31 import org.apache.maven.model.Plugin;
32 import org.apache.maven.model.PluginExecution;
33 import org.apache.maven.model.ReportPlugin;
34 import org.apache.maven.model.ReportSet;
35 import org.apache.maven.monitor.event.EventDispatcher;
36 import org.apache.maven.monitor.event.MavenEvents;
37 import org.apache.maven.plugin.InvalidPluginException;
38 import org.apache.maven.plugin.MojoExecution;
39 import org.apache.maven.plugin.MojoExecutionException;
40 import org.apache.maven.plugin.MojoFailureException;
41 import org.apache.maven.plugin.PluginConfigurationException;
42 import org.apache.maven.plugin.PluginManager;
43 import org.apache.maven.plugin.PluginManagerException;
44 import org.apache.maven.plugin.PluginNotFoundException;
45 import org.apache.maven.plugin.descriptor.MojoDescriptor;
46 import org.apache.maven.plugin.descriptor.PluginDescriptor;
47 import org.apache.maven.plugin.lifecycle.Execution;
48 import org.apache.maven.plugin.lifecycle.Phase;
49 import org.apache.maven.plugin.version.PluginVersionNotFoundException;
50 import org.apache.maven.plugin.version.PluginVersionResolutionException;
51 import org.apache.maven.project.MavenProject;
52 import org.apache.maven.project.artifact.InvalidDependencyVersionException;
53 import org.apache.maven.reporting.MavenReport;
54 import org.apache.maven.settings.Settings;
55 import org.codehaus.plexus.PlexusContainerException;
56 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
57 import org.codehaus.plexus.logging.AbstractLogEnabled;
58 import org.codehaus.plexus.util.StringUtils;
59 import org.codehaus.plexus.util.xml.Xpp3Dom;
60 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
61
62 import java.io.IOException JavaDoc;
63 import java.util.ArrayList JavaDoc;
64 import java.util.Collections JavaDoc;
65 import java.util.HashMap JavaDoc;
66 import java.util.Iterator JavaDoc;
67 import java.util.List JavaDoc;
68 import java.util.Map JavaDoc;
69 import java.util.Stack JavaDoc;
70 import java.util.StringTokenizer JavaDoc;
71
72 /**
73  * @author <a HREF="mailto:jason@maven.org">Jason van Zyl</a>
74  * @author <a HREF="mailto:brett@apache.org">Brett Porter</a>
75  * @version $Id: DefaultLifecycleExecutor.java,v 1.16 2005/03/04 09:04:25
76  * jdcasey Exp $
77  * @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)
78  */

79 public class DefaultLifecycleExecutor
80     extends AbstractLogEnabled
81     implements LifecycleExecutor
82 {
83     // ----------------------------------------------------------------------
84
// Components
85
// ----------------------------------------------------------------------
86

87     private PluginManager pluginManager;
88
89     private ExtensionManager extensionManager;
90
91     private List JavaDoc lifecycles;
92
93     private ArtifactHandlerManager artifactHandlerManager;
94
95     private List JavaDoc defaultReports;
96
97     private Map JavaDoc phaseToLifecycleMap;
98
99     // ----------------------------------------------------------------------
100
//
101
// ----------------------------------------------------------------------
102

103     /**
104      * Execute a task. Each task may be a phase in the lifecycle or the
105      * execution of a mojo.
106      *
107      * @param session
108      * @param rm
109      * @param dispatcher
110      */

111     public void execute( MavenSession session, ReactorManager rm, EventDispatcher dispatcher )
112         throws BuildFailureException, LifecycleExecutionException
113     {
114         // TODO: This is dangerous, particularly when it's just a collection of loose-leaf projects being built
115
// within the same reactor (using an inclusion pattern to gather them up)...
116
MavenProject rootProject = rm.getTopLevelProject();
117
118         List JavaDoc goals = session.getGoals();
119
120         if ( goals.isEmpty() && rootProject != null )
121         {
122             String JavaDoc goal = rootProject.getDefaultGoal();
123
124             if ( goal != null )
125             {
126                 goals = Collections.singletonList( goal );
127             }
128         }
129
130         if ( goals.isEmpty() )
131         {
132             throw new BuildFailureException( "You must specify at least one goal. Try 'install'" );
133         }
134
135         List JavaDoc taskSegments = segmentTaskListByAggregationNeeds( goals, session, rootProject );
136
137         // TODO: probably don't want to do all this up front
138
findExtensions( session );
139
140         executeTaskSegments( taskSegments, rm, session, rootProject, dispatcher );
141     }
142
143     private void findExtensions( MavenSession session )
144         throws LifecycleExecutionException
145     {
146         for ( Iterator JavaDoc i = session.getSortedProjects().iterator(); i.hasNext(); )
147         {
148             MavenProject project = (MavenProject) i.next();
149
150             for ( Iterator JavaDoc j = project.getBuildExtensions().iterator(); j.hasNext(); )
151             {
152                 Extension extension = (Extension) j.next();
153                 try
154                 {
155                     extensionManager.addExtension( extension, project, session.getLocalRepository() );
156                 }
157                 catch ( PlexusContainerException e )
158                 {
159                     throw new LifecycleExecutionException( "Unable to initialise extensions", e );
160                 }
161                 catch ( ArtifactResolutionException e )
162                 {
163                     throw new LifecycleExecutionException( e.getMessage(), e );
164                 }
165                 catch ( ArtifactNotFoundException e )
166                 {
167                     throw new LifecycleExecutionException( e.getMessage(), e );
168                 }
169             }
170
171             try
172             {
173                 Map JavaDoc handlers = findArtifactTypeHandlers( project, session.getSettings(), session.getLocalRepository() );
174
175                 artifactHandlerManager.addHandlers( handlers );
176             }
177             catch ( PluginNotFoundException e )
178             {
179                 throw new LifecycleExecutionException( e.getMessage(), e );
180             }
181         }
182     }
183
184     private void executeTaskSegments( List JavaDoc taskSegments, ReactorManager rm, MavenSession session,
185                                       MavenProject rootProject, EventDispatcher dispatcher )
186         throws LifecycleExecutionException, BuildFailureException
187     {
188         for ( Iterator JavaDoc it = taskSegments.iterator(); it.hasNext(); )
189         {
190             TaskSegment segment = (TaskSegment) it.next();
191
192             if ( segment.aggregate() )
193             {
194                 if ( !rm.isBlackListed( rootProject ) )
195                 {
196                     line();
197
198                     getLogger().info( "Building " + rootProject.getName() );
199
200                     getLogger().info( " " + segment );
201
202                     line();
203
204                     // !! This is ripe for refactoring to an aspect.
205
// Event monitoring.
206
String JavaDoc event = MavenEvents.PROJECT_EXECUTION;
207
208                     long buildStartTime = System.currentTimeMillis();
209
210                     String JavaDoc target = rootProject.getId() + " ( " + segment + " )";
211
212                     dispatcher.dispatchStart( event, target );
213
214                     // only call once, with the top-level project (assumed to be provided as a parameter)...
215
for ( Iterator JavaDoc goalIterator = segment.getTasks().iterator(); goalIterator.hasNext(); )
216                     {
217                         String JavaDoc task = (String JavaDoc) goalIterator.next();
218
219                         executeGoalAndHandleFailures( task, session, rootProject, dispatcher, event, rm, buildStartTime,
220                                                       target );
221                     }
222
223                     rm.registerBuildSuccess( rootProject, System.currentTimeMillis() - buildStartTime );
224
225                     dispatcher.dispatchEnd( event, target );
226                 }
227                 else
228                 {
229                     line();
230
231                     getLogger().info( "SKIPPING " + rootProject.getName() );
232
233                     getLogger().info( " " + segment );
234
235                     getLogger().info(
236                         "This project has been banned from further executions due to previous failures." );
237
238                     line();
239                 }
240             }
241             else
242             {
243                 List JavaDoc sortedProjects = session.getSortedProjects();
244
245                 // iterate over projects, and execute on each...
246
for ( Iterator JavaDoc projectIterator = sortedProjects.iterator(); projectIterator.hasNext(); )
247                 {
248                     MavenProject currentProject = (MavenProject) projectIterator.next();
249
250                     if ( !rm.isBlackListed( currentProject ) )
251                     {
252                         line();
253
254                         getLogger().info( "Building " + currentProject.getName() );
255
256                         getLogger().info( " " + segment );
257
258                         line();
259
260                         // !! This is ripe for refactoring to an aspect.
261
// Event monitoring.
262
String JavaDoc event = MavenEvents.PROJECT_EXECUTION;
263
264                         long buildStartTime = System.currentTimeMillis();
265
266                         String JavaDoc target = currentProject.getId() + " ( " + segment + " )";
267                         dispatcher.dispatchStart( event, target );
268
269                         for ( Iterator JavaDoc goalIterator = segment.getTasks().iterator(); goalIterator.hasNext(); )
270                         {
271                             String JavaDoc task = (String JavaDoc) goalIterator.next();
272
273                             executeGoalAndHandleFailures( task, session, currentProject, dispatcher, event, rm,
274                                                           buildStartTime, target );
275                         }
276
277                         rm.registerBuildSuccess( currentProject, System.currentTimeMillis() - buildStartTime );
278
279                         dispatcher.dispatchEnd( event, target );
280                     }
281                     else
282                     {
283                         line();
284
285                         getLogger().info( "SKIPPING " + currentProject.getName() );
286
287                         getLogger().info( " " + segment );
288
289                         getLogger().info(
290                             "This project has been banned from further executions due to previous failures." );
291
292                         line();
293                     }
294                 }
295             }
296         }
297     }
298
299     private void executeGoalAndHandleFailures( String JavaDoc task, MavenSession session, MavenProject project,
300                                                EventDispatcher dispatcher, String JavaDoc event, ReactorManager rm,
301                                                long buildStartTime, String JavaDoc target )
302         throws BuildFailureException, LifecycleExecutionException
303     {
304         try
305         {
306             executeGoal( task, session, project );
307         }
308         catch ( LifecycleExecutionException e )
309         {
310             dispatcher.dispatchError( event, target, e );
311
312             if ( handleExecutionFailure( rm, project, e, task, buildStartTime ) )
313             {
314                 throw e;
315             }
316         }
317         catch ( BuildFailureException e )
318         {
319             dispatcher.dispatchError( event, target, e );
320
321             if ( handleExecutionFailure( rm, project, e, task, buildStartTime ) )
322             {
323                 throw e;
324             }
325         }
326     }
327
328     private boolean handleExecutionFailure( ReactorManager rm, MavenProject project, Exception JavaDoc e, String JavaDoc task,
329                                             long buildStartTime )
330     {
331         rm.registerBuildFailure( project, e, task, System.currentTimeMillis() - buildStartTime );
332
333         if ( ReactorManager.FAIL_FAST.equals( rm.getFailureBehavior() ) )
334         {
335             return true;
336         }
337         else if ( ReactorManager.FAIL_AT_END.equals( rm.getFailureBehavior() ) )
338         {
339             rm.blackList( project );
340         }
341         // if NEVER, don't blacklist
342
return false;
343     }
344
345     private List JavaDoc segmentTaskListByAggregationNeeds( List JavaDoc tasks, MavenSession session, MavenProject project )
346         throws LifecycleExecutionException, BuildFailureException
347     {
348         List JavaDoc segments = new ArrayList JavaDoc();
349
350         if ( project != null )
351         {
352
353             TaskSegment currentSegment = null;
354             for ( Iterator JavaDoc it = tasks.iterator(); it.hasNext(); )
355             {
356                 String JavaDoc task = (String JavaDoc) it.next();
357
358                 // if it's a phase, then we don't need to check whether it's an aggregator.
359
// simply add it to the current task partition.
360
if ( getPhaseToLifecycleMap().containsKey( task ) )
361                 {
362                     if ( currentSegment != null && currentSegment.aggregate() )
363                     {
364                         segments.add( currentSegment );
365                         currentSegment = null;
366                     }
367
368                     if ( currentSegment == null )
369                     {
370                         currentSegment = new TaskSegment();
371                     }
372
373                     currentSegment.add( task );
374                 }
375                 else
376                 {
377                     MojoDescriptor mojo = null;
378                     try
379                     {
380                         // definitely a CLI goal, can use prefix
381
mojo = getMojoDescriptor( task, session, project, task, true, false );
382                     }
383                     catch ( PluginNotFoundException e )
384                     {
385                         // TODO: shouldn't hit this, investigate using the same resolution logic as otheres for plugins in the reactor
386
getLogger().info(
387                             "Cannot find mojo descriptor for: \'" + task + "\' - Treating as non-aggregator." );
388                         getLogger().debug( "", e );
389                     }
390
391                     // if the mojo descriptor was found, determine aggregator status according to:
392
// 1. whether the mojo declares itself an aggregator
393
// 2. whether the mojo DOES NOT require a project to function (implicitly avoid reactor)
394
if ( mojo != null && ( mojo.isAggregator() || !mojo.isProjectRequired() ) )
395                     {
396                         if ( currentSegment != null && !currentSegment.aggregate() )
397                         {
398                             segments.add( currentSegment );
399                             currentSegment = null;
400                         }
401
402                         if ( currentSegment == null )
403                         {
404                             currentSegment = new TaskSegment( true );
405                         }
406
407                         currentSegment.add( task );
408                     }
409                     else
410                     {
411                         if ( currentSegment != null && currentSegment.aggregate() )
412                         {
413                             segments.add( currentSegment );
414                             currentSegment = null;
415                         }
416
417                         if ( currentSegment == null )
418                         {
419                             currentSegment = new TaskSegment();
420                         }
421
422                         currentSegment.add( task );
423                     }
424                 }
425             }
426
427             segments.add( currentSegment );
428         }
429         else
430         {
431             TaskSegment segment = new TaskSegment( false );
432             for ( Iterator JavaDoc i = tasks.iterator(); i.hasNext(); )
433             {
434                 segment.add( (String JavaDoc) i.next() );
435             }
436             segments.add( segment );
437         }
438
439         return segments;
440     }
441
442     private void executeGoal( String JavaDoc task, MavenSession session, MavenProject project )
443         throws LifecycleExecutionException, BuildFailureException
444     {
445         try
446         {
447             Stack JavaDoc forkEntryPoints = new Stack JavaDoc();
448             if ( getPhaseToLifecycleMap().containsKey( task ) )
449             {
450                 Lifecycle lifecycle = getLifecycleForPhase( task );
451
452                 // we have a lifecycle phase, so lets bind all the necessary goals
453
Map JavaDoc lifecycleMappings = constructLifecycleMappings( session, task, project, lifecycle );
454                 executeGoalWithLifecycle( task, forkEntryPoints, session, lifecycleMappings, project, lifecycle );
455             }
456             else
457             {
458                 executeStandaloneGoal( task, forkEntryPoints, session, project );
459             }
460         }
461         catch ( PluginNotFoundException e )
462         {
463             throw new BuildFailureException( "A required plugin was not found: " + e.getMessage(), e );
464         }
465     }
466
467     private void executeGoalWithLifecycle( String JavaDoc task, Stack JavaDoc forkEntryPoints, MavenSession session,
468                                            Map JavaDoc lifecycleMappings, MavenProject project, Lifecycle lifecycle )
469         throws LifecycleExecutionException, BuildFailureException, PluginNotFoundException
470     {
471         List JavaDoc goals = processGoalChain( task, lifecycleMappings, lifecycle );
472
473         if ( !goals.isEmpty() )
474         {
475             executeGoals( goals, forkEntryPoints, session, project );
476         }
477         else
478         {
479             getLogger().info( "No goals needed for project - skipping" );
480         }
481     }
482
483     private void executeStandaloneGoal( String JavaDoc task, Stack JavaDoc forkEntryPoints, MavenSession session, MavenProject project )
484         throws LifecycleExecutionException, BuildFailureException, PluginNotFoundException
485     {
486         // guaranteed to come from the CLI and not be part of a phase
487
MojoDescriptor mojoDescriptor = getMojoDescriptor( task, session, project, task, true, false );
488         executeGoals( Collections.singletonList( new MojoExecution( mojoDescriptor ) ), forkEntryPoints, session,
489                       project );
490     }
491
492     private void executeGoals( List JavaDoc goals, Stack JavaDoc forkEntryPoints, MavenSession session, MavenProject project )
493         throws LifecycleExecutionException, BuildFailureException, PluginNotFoundException
494     {
495         for ( Iterator JavaDoc i = goals.iterator(); i.hasNext(); )
496         {
497             MojoExecution mojoExecution = (MojoExecution) i.next();
498
499             MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
500
501             if ( mojoDescriptor.getExecutePhase() != null || mojoDescriptor.getExecuteGoal() != null )
502             {
503                 forkEntryPoints.push( mojoDescriptor );
504
505                 forkLifecycle( mojoDescriptor, forkEntryPoints, session, project );
506
507                 forkEntryPoints.pop();
508             }
509
510             if ( mojoDescriptor.isRequiresReports() )
511             {
512                 List JavaDoc reports = getReports( project, mojoExecution, session );
513
514                 mojoExecution.setReports( reports );
515
516                 for ( Iterator JavaDoc j = mojoExecution.getForkedExecutions().iterator(); j.hasNext(); )
517                 {
518                     MojoExecution forkedExecution = (MojoExecution) j.next();
519                     MojoDescriptor descriptor = forkedExecution.getMojoDescriptor();
520
521                     if ( descriptor.getExecutePhase() != null )
522                     {
523                         forkEntryPoints.push( descriptor );
524
525                         forkLifecycle( descriptor, forkEntryPoints, session, project );
526
527                         forkEntryPoints.pop();
528                     }
529                 }
530             }
531
532             try
533             {
534                 pluginManager.executeMojo( project, mojoExecution, session );
535             }
536             catch ( PluginManagerException e )
537             {
538                 throw new LifecycleExecutionException( "Internal error in the plugin manager executing goal '" +
539                     mojoDescriptor.getId() + "': " + e.getMessage(), e );
540             }
541             catch ( ArtifactNotFoundException e )
542             {
543                 throw new LifecycleExecutionException( e.getMessage(), e );
544             }
545             catch ( InvalidDependencyVersionException e )
546             {
547                 throw new LifecycleExecutionException( e.getMessage(), e );
548             }
549             catch ( ArtifactResolutionException e )
550             {
551                 throw new LifecycleExecutionException( e.getMessage(), e );
552             }
553             catch ( MojoFailureException e )
554             {
555                 throw new BuildFailureException( e.getMessage(), e );
556             }
557             catch ( MojoExecutionException e )
558             {
559                 throw new LifecycleExecutionException( e.getMessage(), e );
560             }
561             catch ( PluginConfigurationException e )
562             {
563                 throw new LifecycleExecutionException( e.getMessage(), e );
564             }
565         }
566     }
567
568     private List JavaDoc getReports( MavenProject project, MojoExecution mojoExecution, MavenSession session )
569         throws LifecycleExecutionException, PluginNotFoundException
570     {
571         List JavaDoc reportPlugins = project.getReportPlugins();
572
573         if ( project.getModel().getReports() != null )
574         {
575             getLogger().error(
576                 "Plugin contains a <reports/> section: this is IGNORED - please use <reporting/> instead." );
577         }
578
579         if ( project.getReporting() == null || !project.getReporting().isExcludeDefaults() )
580         {
581             if ( reportPlugins == null )
582             {
583                 reportPlugins = new ArrayList JavaDoc();
584             }
585             else
586             {
587                 reportPlugins = new ArrayList JavaDoc( reportPlugins );
588             }
589
590             for ( Iterator JavaDoc i = defaultReports.iterator(); i.hasNext(); )
591             {
592                 String JavaDoc report = (String JavaDoc) i.next();
593
594                 StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc( report, ":" );
595                 if ( tok.countTokens() != 2 )
596                 {
597                     getLogger().warn( "Invalid default report ignored: '" + report + "' (must be groupId:artifactId)" );
598                 }
599                 else
600                 {
601                     String JavaDoc groupId = tok.nextToken();
602                     String JavaDoc artifactId = tok.nextToken();
603
604                     boolean found = false;
605                     for ( Iterator JavaDoc j = reportPlugins.iterator(); j.hasNext() && !found; )
606                     {
607                         ReportPlugin reportPlugin = (ReportPlugin) j.next();
608                         if ( reportPlugin.getGroupId().equals( groupId ) &&
609                             reportPlugin.getArtifactId().equals( artifactId ) )
610                         {
611                             found = true;
612                         }
613                     }
614
615                     if ( !found )
616                     {
617                         ReportPlugin reportPlugin = new ReportPlugin();
618                         reportPlugin.setGroupId( groupId );
619                         reportPlugin.setArtifactId( artifactId );
620                         reportPlugins.add( reportPlugin );
621                     }
622                 }
623             }
624         }
625
626         List JavaDoc reports = new ArrayList JavaDoc();
627         if ( reportPlugins != null )
628         {
629             for ( Iterator JavaDoc it = reportPlugins.iterator(); it.hasNext(); )
630             {
631                 ReportPlugin reportPlugin = (ReportPlugin) it.next();
632
633                 List JavaDoc reportSets = reportPlugin.getReportSets();
634
635                 if ( reportSets == null || reportSets.isEmpty() )
636                 {
637                     reports.addAll( getReports( reportPlugin, null, project, session, mojoExecution ) );
638                 }
639                 else
640                 {
641                     for ( Iterator JavaDoc j = reportSets.iterator(); j.hasNext(); )
642                     {
643                         ReportSet reportSet = (ReportSet) j.next();
644
645                         reports.addAll( getReports( reportPlugin, reportSet, project, session, mojoExecution ) );
646                     }
647                 }
648             }
649         }
650         return reports;
651     }
652
653     private List JavaDoc getReports( ReportPlugin reportPlugin, ReportSet reportSet, MavenProject project, MavenSession session,
654                              MojoExecution mojoExecution )
655         throws LifecycleExecutionException, PluginNotFoundException
656     {
657         PluginDescriptor pluginDescriptor = verifyReportPlugin( reportPlugin, project, session );
658
659         List JavaDoc reports = new ArrayList JavaDoc();
660         for ( Iterator JavaDoc i = pluginDescriptor.getMojos().iterator(); i.hasNext(); )
661         {
662             MojoDescriptor mojoDescriptor = (MojoDescriptor) i.next();
663
664             // TODO: check ID is correct for reports
665
// if the POM configured no reports, give all from plugin
666
if ( reportSet == null || reportSet.getReports().contains( mojoDescriptor.getGoal() ) )
667             {
668                 String JavaDoc id = null;
669                 if ( reportSet != null )
670                 {
671                     id = reportSet.getId();
672                 }
673
674                 MojoExecution reportExecution = new MojoExecution( mojoDescriptor, id );
675
676                 try
677                 {
678                     MavenReport reportMojo = pluginManager.getReport( project, reportExecution, session );
679
680                     // Comes back null if it was a plugin, not a report - these are mojos in the reporting plugins that are not reports
681
if ( reportMojo != null )
682                     {
683                         reports.add( reportMojo );
684                         mojoExecution.addMojoExecution( reportExecution );
685                     }
686                 }
687                 catch ( PluginManagerException e )
688                 {
689                     throw new LifecycleExecutionException(
690                         "Error getting reports from the plugin '" + reportPlugin.getKey() + "': " + e.getMessage(), e );
691                 }
692                 catch ( PluginConfigurationException e )
693                 {
694                     throw new LifecycleExecutionException(
695                         "Error getting reports from the plugin '" + reportPlugin.getKey() + "'", e );
696                 }
697                 catch ( ArtifactNotFoundException e )
698                 {
699                     throw new LifecycleExecutionException( e.getMessage(), e );
700                 }
701                 catch ( ArtifactResolutionException e )
702                 {
703                     throw new LifecycleExecutionException( e.getMessage(), e );
704                 }
705             }
706         }
707         return reports;
708     }
709
710     private void forkLifecycle( MojoDescriptor mojoDescriptor, Stack JavaDoc ancestorLifecycleForkers, MavenSession session,
711                                 MavenProject project )
712         throws LifecycleExecutionException, BuildFailureException, PluginNotFoundException
713     {
714         PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
715         getLogger().info( "Preparing " + pluginDescriptor.getGoalPrefix() + ":" + mojoDescriptor.getGoal() );
716
717         if ( mojoDescriptor.isAggregator() )
718         {
719             for ( Iterator JavaDoc i = session.getSortedProjects().iterator(); i.hasNext(); )
720             {
721                 MavenProject reactorProject = (MavenProject) i.next();
722
723                 line();
724
725                 getLogger().info( "Building " + reactorProject.getName() );
726
727                 line();
728
729                 forkProjectLifecycle( mojoDescriptor, ancestorLifecycleForkers, session, reactorProject );
730             }
731         }
732         else
733         {
734             forkProjectLifecycle( mojoDescriptor, ancestorLifecycleForkers, session, project );
735         }
736     }
737
738     private void forkProjectLifecycle( MojoDescriptor mojoDescriptor, Stack JavaDoc forkEntryPoints, MavenSession session,
739                                        MavenProject project )
740         throws LifecycleExecutionException, BuildFailureException, PluginNotFoundException
741     {
742         forkEntryPoints.push( mojoDescriptor );
743
744         PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
745
746         String JavaDoc targetPhase = mojoDescriptor.getExecutePhase();
747
748         Map JavaDoc lifecycleMappings = null;
749         if ( targetPhase != null )
750         {
751             Lifecycle lifecycle = getLifecycleForPhase( targetPhase );
752
753             // Create new lifecycle
754
lifecycleMappings = constructLifecycleMappings( session, targetPhase, project, lifecycle );
755
756             String JavaDoc executeLifecycle = mojoDescriptor.getExecuteLifecycle();
757             if ( executeLifecycle != null )
758             {
759                 org.apache.maven.plugin.lifecycle.Lifecycle lifecycleOverlay;
760                 try
761                 {
762                     lifecycleOverlay = pluginDescriptor.getLifecycleMapping( executeLifecycle );
763                 }
764                 catch ( IOException JavaDoc e )
765                 {
766                     throw new LifecycleExecutionException( "Unable to read lifecycle mapping file: " + e.getMessage(),
767                                                            e );
768                 }
769                 catch ( XmlPullParserException e )
770                 {
771                     throw new LifecycleExecutionException( "Unable to parse lifecycle mapping file: " + e.getMessage(),
772                                                            e );
773                 }
774
775                 if ( lifecycleOverlay == null )
776                 {
777                     throw new LifecycleExecutionException( "Lifecycle '" + executeLifecycle + "' not found in plugin" );
778                 }
779
780                 for ( Iterator JavaDoc i = lifecycleOverlay.getPhases().iterator(); i.hasNext(); )
781                 {
782                     Phase phase = (Phase) i.next();
783                     for ( Iterator JavaDoc j = phase.getExecutions().iterator(); j.hasNext(); )
784                     {
785                         Execution exec = (Execution) j.next();
786
787                         for ( Iterator JavaDoc k = exec.getGoals().iterator(); k.hasNext(); )
788                         {
789                             String JavaDoc goal = (String JavaDoc) k.next();
790
791                             PluginDescriptor lifecyclePluginDescriptor;
792                             String JavaDoc lifecycleGoal;
793
794                             // Here we are looking to see if we have a mojo from an external plugin.
795
// If we do then we need to lookup the plugin descriptor for the externally
796
// referenced plugin so that we can overly the execution into the lifecycle.
797
// An example of this is the corbertura plugin that needs to call the surefire
798
// plugin in forking mode.
799
//
800
//<phase>
801
// <id>test</id>
802
// <executions>
803
// <execution>
804
// <goals>
805
// <goal>org.apache.maven.plugins:maven-surefire-plugin:test</goal>
806
// </goals>
807
// <configuration>
808
// <classesDirectory>${project.build.directory}/generated-classes/cobertura</classesDirectory>
809
// <ignoreFailures>true</ignoreFailures>
810
// <forkMode>once</forkMode>
811
// </configuration>
812
// </execution>
813
// </executions>
814
//</phase>
815

816                             // ----------------------------------------------------------------------
817
//
818
// ----------------------------------------------------------------------
819

820                             if ( goal.indexOf( ":" ) > 0 )
821                             {
822                                 String JavaDoc[] s = StringUtils.split( goal, ":" );
823
824                                 String JavaDoc groupId = s[0];
825                                 String JavaDoc artifactId = s[1];
826                                 lifecycleGoal = s[2];
827
828                                 Plugin plugin = new Plugin();
829                                 plugin.setGroupId( groupId );
830                                 plugin.setArtifactId( artifactId );
831                                 lifecyclePluginDescriptor = verifyPlugin( plugin, project, session.getSettings(),
832                                                                           session.getLocalRepository() );
833                                 if ( lifecyclePluginDescriptor == null )
834                                 {
835                                     throw new LifecycleExecutionException(
836                                         "Unable to find plugin " + groupId + ":" + artifactId );
837                                 }
838                             }
839                             else
840                             {
841                                 lifecyclePluginDescriptor = pluginDescriptor;
842                                 lifecycleGoal = goal;
843                             }
844
845                             Xpp3Dom configuration = (Xpp3Dom) exec.getConfiguration();
846                             if ( phase.getConfiguration() != null )
847                             {
848                                 configuration = Xpp3Dom.mergeXpp3Dom( new Xpp3Dom( (Xpp3Dom) phase.getConfiguration() ),
849                                                                       configuration );
850                             }
851
852                             MojoDescriptor desc = getMojoDescriptor( lifecyclePluginDescriptor, lifecycleGoal );
853                             MojoExecution mojoExecution = new MojoExecution( desc, configuration );
854                             addToLifecycleMappings( lifecycleMappings, phase.getId(), mojoExecution,
855                                                     session.getSettings() );
856                         }
857                     }
858
859                     if ( phase.getConfiguration() != null )
860                     {
861                         // Merge in general configuration for a phase.
862
// TODO: this is all kind of backwards from the POMM. Let's align it all under 2.1.
863
// We should create a new lifecycle executor for modelVersion >5.0.0
864
for ( Iterator JavaDoc j = lifecycleMappings.values().iterator(); j.hasNext(); )
865                         {
866                             List JavaDoc tasks = (List JavaDoc) j.next();
867
868                             for ( Iterator JavaDoc k = tasks.iterator(); k.hasNext(); )
869                             {
870                                 MojoExecution exec = (MojoExecution) k.next();
871
872                                 Xpp3Dom configuration = Xpp3Dom.mergeXpp3Dom(
873                                     new Xpp3Dom( (Xpp3Dom) phase.getConfiguration() ), exec.getConfiguration() );
874
875                                 exec.setConfiguration( configuration );
876                             }
877                         }
878                     }
879
880                 }
881             }
882
883             removeFromLifecycle( forkEntryPoints, lifecycleMappings );
884         }
885
886         MavenProject executionProject = new MavenProject( project );
887         if ( targetPhase != null )
888         {
889             Lifecycle lifecycle = getLifecycleForPhase( targetPhase );
890
891             executeGoalWithLifecycle( targetPhase, forkEntryPoints, session, lifecycleMappings, executionProject,
892                                       lifecycle );
893         }
894         else
895         {
896             String JavaDoc goal = mojoDescriptor.getExecuteGoal();
897             MojoDescriptor desc = getMojoDescriptor( pluginDescriptor, goal );
898             executeGoals( Collections.singletonList( new MojoExecution( desc ) ), forkEntryPoints, session,
899                           executionProject );
900         }
901         project.setExecutionProject( executionProject );
902     }
903
904     private Lifecycle getLifecycleForPhase( String JavaDoc phase )
905         throws BuildFailureException, LifecycleExecutionException
906     {
907         Lifecycle lifecycle = (Lifecycle) getPhaseToLifecycleMap().get( phase );
908
909         if ( lifecycle == null )
910         {
911             throw new BuildFailureException( "Unable to find lifecycle for phase '" + phase + "'" );
912         }
913         return lifecycle;
914     }
915
916     private MojoDescriptor getMojoDescriptor( PluginDescriptor pluginDescriptor, String JavaDoc goal )
917         throws LifecycleExecutionException
918     {
919         MojoDescriptor desc = pluginDescriptor.getMojo( goal );
920
921         if ( desc == null )
922         {
923             String JavaDoc message =
924                 "Required goal '" + goal + "' not found in plugin '" + pluginDescriptor.getGoalPrefix() + "'";
925             int index = goal.indexOf( ':' );
926             if ( index >= 0 )
927             {
928                 String JavaDoc prefix = goal.substring( index + 1 );
929                 if ( prefix.equals( pluginDescriptor.getGoalPrefix() ) )
930                 {
931                     message = message + " (goals should not be prefixed - try '" + prefix + "')";
932                 }
933             }
934             throw new LifecycleExecutionException( message );
935         }
936         return desc;
937     }
938
939     private void removeFromLifecycle( Stack JavaDoc lifecycleForkers, Map JavaDoc lifecycleMappings )
940     {
941         for ( Iterator JavaDoc it = lifecycleForkers.iterator(); it.hasNext(); )
942         {
943             MojoDescriptor mojoDescriptor = (MojoDescriptor) it.next();
944
945             for ( Iterator JavaDoc lifecycleIterator = lifecycleMappings.values().iterator(); lifecycleIterator.hasNext(); )
946             {
947                 List JavaDoc tasks = (List JavaDoc) lifecycleIterator.next();
948
949                 boolean removed = false;
950                 for ( Iterator JavaDoc taskIterator = tasks.iterator(); taskIterator.hasNext(); )
951                 {
952                     MojoExecution execution = (MojoExecution) taskIterator.next();
953
954                     if ( mojoDescriptor.equals( execution.getMojoDescriptor() ) )
955                     {
956                         taskIterator.remove();
957                         removed = true;
958                     }
959                 }
960
961                 if ( removed )
962                 {
963                     getLogger().warn( "Removing: " + mojoDescriptor.getGoal() +
964                         " from forked lifecycle, to prevent recursive invocation." );
965                 }
966             }
967         }
968     }
969
970     private Map JavaDoc constructLifecycleMappings( MavenSession session, String JavaDoc selectedPhase, MavenProject project,
971                                             Lifecycle lifecycle )
972         throws LifecycleExecutionException, BuildFailureException, PluginNotFoundException
973     {
974         // first, bind those associated with the packaging
975
Map JavaDoc lifecycleMappings = bindLifecycleForPackaging( session, selectedPhase, project, lifecycle );
976
977         // next, loop over plugins and for any that have a phase, bind it
978
for ( Iterator JavaDoc i = project.getBuildPlugins().iterator(); i.hasNext(); )
979         {
980             Plugin plugin = (Plugin) i.next();
981
982             bindPluginToLifecycle( plugin, session, lifecycleMappings, project );
983         }
984
985         return lifecycleMappings;
986     }
987
988     private Map JavaDoc bindLifecycleForPackaging( MavenSession session, String JavaDoc selectedPhase, MavenProject project,
989                                            Lifecycle lifecycle )
990         throws LifecycleExecutionException, BuildFailureException, PluginNotFoundException
991     {
992         Map JavaDoc mappings = findMappingsForLifecycle( session, project, lifecycle );
993
994         List JavaDoc optionalMojos = findOptionalMojosForLifecycle( session, project, lifecycle );
995
996         Map JavaDoc lifecycleMappings = new HashMap JavaDoc();
997
998         for ( Iterator JavaDoc i = lifecycle.getPhases().iterator(); i.hasNext(); )
999         {
1000            String JavaDoc phase = (String JavaDoc) i.next();
1001
1002            String JavaDoc phaseTasks = (String JavaDoc) mappings.get( phase );
1003
1004            if ( phaseTasks != null )
1005            {
1006                for ( StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc( phaseTasks, "," ); tok.hasMoreTokens(); )
1007                {
1008                    String JavaDoc goal = tok.nextToken().trim();
1009
1010                    // Not from the CLI, don't use prefix
1011
MojoDescriptor mojoDescriptor = getMojoDescriptor( goal, session, project, selectedPhase, false,
1012                                                                       optionalMojos.contains( goal ) );
1013
1014                    if ( mojoDescriptor == null )
1015                    {
1016                        continue;
1017                    }
1018
1019                    if ( mojoDescriptor.isDirectInvocationOnly() )
1020                    {
1021                        throw new LifecycleExecutionException( "Mojo: \'" + goal +
1022                            "\' requires direct invocation. It cannot be used as part of lifecycle: \'" +
1023                            project.getPackaging() + "\'." );
1024                    }
1025
1026                    addToLifecycleMappings( lifecycleMappings, phase, new MojoExecution( mojoDescriptor ),
1027                                            session.getSettings() );
1028                }
1029            }
1030
1031            if ( phase.equals( selectedPhase ) )
1032            {
1033                break;
1034            }
1035        }
1036
1037        return lifecycleMappings;
1038    }
1039
1040    private Map JavaDoc findMappingsForLifecycle( MavenSession session, MavenProject project, Lifecycle lifecycle )
1041        throws LifecycleExecutionException, PluginNotFoundException
1042    {
1043        String JavaDoc packaging = project.getPackaging();
1044        Map JavaDoc mappings = null;
1045
1046        LifecycleMapping m = (LifecycleMapping) findExtension( project, LifecycleMapping.ROLE, packaging,
1047                                                               session.getSettings(), session.getLocalRepository() );
1048        if ( m != null )
1049        {
1050            mappings = m.getPhases( lifecycle.getId() );
1051        }
1052
1053        Map JavaDoc defaultMappings = lifecycle.getDefaultPhases();
1054
1055        if ( mappings == null )
1056        {
1057            try
1058            {
1059                m = (LifecycleMapping) session.lookup( LifecycleMapping.ROLE, packaging );
1060                mappings = m.getPhases( lifecycle.getId() );
1061            }
1062            catch ( ComponentLookupException e )
1063            {
1064                if ( defaultMappings == null )
1065                {
1066                    throw new LifecycleExecutionException(
1067                        "Cannot find lifecycle mapping for packaging: \'" + packaging + "\'.", e );
1068                }
1069            }
1070        }
1071
1072        if ( mappings == null )
1073        {
1074            if ( defaultMappings == null )
1075            {
1076                throw new LifecycleExecutionException(
1077                    "Cannot find lifecycle mapping for packaging: \'" + packaging + "\', and there is no default" );
1078            }
1079            else
1080            {
1081                mappings = defaultMappings;
1082            }
1083        }
1084
1085        return mappings;
1086    }
1087
1088    private List JavaDoc findOptionalMojosForLifecycle( MavenSession session, MavenProject project, Lifecycle lifecycle )
1089        throws LifecycleExecutionException, PluginNotFoundException
1090    {
1091        String JavaDoc packaging = project.getPackaging();
1092        List JavaDoc optionalMojos = null;
1093
1094        LifecycleMapping m = (LifecycleMapping) findExtension( project, LifecycleMapping.ROLE, packaging, session
1095            .getSettings(), session.getLocalRepository() );
1096
1097        if ( m != null )
1098        {
1099            optionalMojos = m.getOptionalMojos( lifecycle.getId() );
1100        }
1101
1102        if ( optionalMojos == null )
1103        {
1104            try
1105            {
1106                m = (LifecycleMapping) session.lookup( LifecycleMapping.ROLE, packaging );
1107                optionalMojos = m.getOptionalMojos( lifecycle.getId() );
1108            }
1109            catch ( ComponentLookupException e )
1110            {
1111                getLogger().debug( "Error looking up lifecycle mapping to retrieve optional mojos. Lifecycle ID: " +
1112                    lifecycle.getId() + ". Error: " + e.getMessage(), e );
1113            }
1114        }
1115
1116        if ( optionalMojos == null )
1117        {
1118            optionalMojos = Collections.EMPTY_LIST;
1119        }
1120
1121        return optionalMojos;
1122    }
1123
1124    private Object JavaDoc findExtension( MavenProject project, String JavaDoc role, String JavaDoc roleHint, Settings settings,
1125                                  ArtifactRepository localRepository )
1126        throws LifecycleExecutionException, PluginNotFoundException
1127    {
1128        Object JavaDoc pluginComponent = null;
1129
1130        for ( Iterator JavaDoc i = project.getBuildPlugins().iterator(); i.hasNext() && pluginComponent == null; )
1131        {
1132            Plugin plugin = (Plugin) i.next();
1133
1134            if ( plugin.isExtensions() )
1135            {
1136                verifyPlugin( plugin, project, settings, localRepository );
1137
1138                // TODO: if moved to the plugin manager we already have the descriptor from above and so do can lookup the container directly
1139
try
1140                {
1141                    pluginComponent = pluginManager.getPluginComponent( plugin, role, roleHint );
1142                }
1143                catch ( ComponentLookupException e )
1144                {
1145                    getLogger().debug( "Unable to find the lifecycle component in the extension", e );
1146                }
1147                catch ( PluginManagerException e )
1148                {
1149                    throw new LifecycleExecutionException(
1150                        "Error getting extensions from the plugin '" + plugin.getKey() + "': " + e.getMessage(), e );
1151                }
1152            }
1153        }
1154        return pluginComponent;
1155    }
1156
1157    /**
1158     * @todo Not particularly happy about this. Would like WagonManager and ArtifactTypeHandlerManager to be able to
1159     * lookup directly, or have them passed in
1160     */

1161    private Map JavaDoc findArtifactTypeHandlers( MavenProject project, Settings settings, ArtifactRepository localRepository )
1162        throws LifecycleExecutionException, PluginNotFoundException
1163    {
1164        Map JavaDoc map = new HashMap JavaDoc();
1165        for ( Iterator JavaDoc i = project.getBuildPlugins().iterator(); i.hasNext(); )
1166        {
1167            Plugin plugin = (Plugin) i.next();
1168
1169            if ( plugin.isExtensions() )
1170            {
1171                verifyPlugin( plugin, project, settings, localRepository );
1172
1173                // TODO: if moved to the plugin manager we already have the descriptor from above and so do can lookup the container directly
1174
try
1175                {
1176                    Map JavaDoc components = pluginManager.getPluginComponents( plugin, ArtifactHandler.ROLE );
1177                    map.putAll( components );
1178                }
1179                catch ( ComponentLookupException e )
1180                {
1181                    getLogger().debug( "Unable to find the lifecycle component in the extension", e );
1182                }
1183                catch ( PluginManagerException e )
1184                {
1185                    throw new LifecycleExecutionException( "Error looking up available components from plugin '" +
1186                        plugin.getKey() + "': " + e.getMessage(), e );
1187                }
1188
1189                // shudder...
1190
for ( Iterator JavaDoc j = map.values().iterator(); j.hasNext(); )
1191                {
1192                    ArtifactHandler handler = (ArtifactHandler) j.next();
1193                    if ( project.getPackaging().equals( handler.getPackaging() ) )
1194                    {
1195                        project.getArtifact().setArtifactHandler( handler );
1196                    }
1197                }
1198            }
1199        }
1200        return map;
1201    }
1202
1203    /**
1204     * Take each mojo contained with a plugin, look to see whether it contributes to a
1205     * phase in the lifecycle and if it does place it at the end of the list of goals
1206     * to execute for that given phase.
1207     *
1208     * @param project
1209     * @param session
1210     */

1211    private void bindPluginToLifecycle( Plugin plugin, MavenSession session, Map JavaDoc phaseMap, MavenProject project )
1212        throws LifecycleExecutionException, PluginNotFoundException
1213    {
1214        Settings settings = session.getSettings();
1215
1216        PluginDescriptor pluginDescriptor =
1217            verifyPlugin( plugin, project, session.getSettings(), session.getLocalRepository() );
1218
1219        if ( pluginDescriptor.getMojos() != null && !pluginDescriptor.getMojos().isEmpty() )
1220        {
1221            // use the plugin if inherit was true in a base class, or it is in the current POM, otherwise use the default inheritence setting
1222
if ( plugin.isInheritanceApplied() || pluginDescriptor.isInheritedByDefault() )
1223            {
1224                if ( plugin.getGoals() != null )
1225                {
1226                    getLogger().error(
1227                        "Plugin contains a <goals/> section: this is IGNORED - please use <executions/> instead." );
1228                }
1229
1230                List JavaDoc executions = plugin.getExecutions();
1231
1232                if ( executions != null )
1233                {
1234                    for ( Iterator JavaDoc it = executions.iterator(); it.hasNext(); )
1235                    {
1236                        PluginExecution execution = (PluginExecution) it.next();
1237
1238                        bindExecutionToLifecycle( pluginDescriptor, phaseMap, execution, settings );
1239                    }
1240                }
1241            }
1242        }
1243    }
1244
1245    private PluginDescriptor verifyPlugin( Plugin plugin, MavenProject project, Settings settings,
1246                                           ArtifactRepository localRepository )
1247        throws LifecycleExecutionException, PluginNotFoundException
1248    {
1249        PluginDescriptor pluginDescriptor;
1250        try
1251        {
1252            pluginDescriptor = pluginManager.verifyPlugin( plugin, project, settings, localRepository );
1253        }
1254        catch ( PluginManagerException e )
1255        {
1256            throw new LifecycleExecutionException(
1257                "Internal error in the plugin manager getting plugin '" + plugin.getKey() + "': " + e.getMessage(), e );
1258        }
1259        catch ( PluginVersionResolutionException e )
1260        {
1261            throw new LifecycleExecutionException( e.getMessage(), e );
1262        }
1263        catch ( InvalidVersionSpecificationException e )
1264        {
1265            throw new LifecycleExecutionException( e.getMessage(), e );
1266        }
1267        catch ( InvalidPluginException e )
1268        {
1269            throw new LifecycleExecutionException( e.getMessage(), e );
1270        }
1271        catch ( ArtifactNotFoundException e )
1272        {
1273            throw new LifecycleExecutionException( e.getMessage(), e );
1274        }
1275        catch ( ArtifactResolutionException e )
1276        {
1277            throw new LifecycleExecutionException( e.getMessage(), e );
1278        }
1279        catch ( PluginVersionNotFoundException e )
1280        {
1281            throw new LifecycleExecutionException( e.getMessage(), e );
1282        }
1283        return pluginDescriptor;
1284    }
1285
1286    private PluginDescriptor verifyReportPlugin( ReportPlugin plugin, MavenProject project, MavenSession session )
1287        throws LifecycleExecutionException, PluginNotFoundException
1288    {
1289        PluginDescriptor pluginDescriptor;
1290        try
1291        {
1292            pluginDescriptor = pluginManager.verifyReportPlugin( plugin, project, session );
1293        }
1294        catch ( PluginManagerException e )
1295        {
1296            throw new LifecycleExecutionException(
1297                "Internal error in the plugin manager getting report '" + plugin.getKey() + "': " + e.getMessage(), e );
1298        }
1299        catch ( PluginVersionResolutionException e )
1300        {
1301            throw new LifecycleExecutionException( e.getMessage(), e );
1302        }
1303        catch ( InvalidVersionSpecificationException e )
1304        {
1305            throw new LifecycleExecutionException( e.getMessage(), e );
1306        }
1307        catch ( InvalidPluginException e )
1308        {
1309            throw new LifecycleExecutionException( e.getMessage(), e );
1310        }
1311        catch ( ArtifactNotFoundException e )
1312        {
1313            throw new LifecycleExecutionException( e.getMessage(), e );
1314        }
1315        catch ( ArtifactResolutionException e )
1316        {
1317            throw new LifecycleExecutionException( e.getMessage(), e );
1318        }
1319        catch ( PluginVersionNotFoundException e )
1320        {
1321            throw new LifecycleExecutionException( e.getMessage(), e );
1322        }
1323        return pluginDescriptor;
1324    }
1325
1326    private void bindExecutionToLifecycle( PluginDescriptor pluginDescriptor, Map JavaDoc phaseMap, PluginExecution execution,
1327                                           Settings settings )
1328        throws LifecycleExecutionException
1329    {
1330        for ( Iterator JavaDoc i = execution.getGoals().iterator(); i.hasNext(); )
1331        {
1332            String JavaDoc goal = (String JavaDoc) i.next();
1333
1334            MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( goal );
1335            if ( mojoDescriptor == null )
1336            {
1337                throw new LifecycleExecutionException(
1338                    "'" + goal + "' was specified in an execution, but not found in the plugin" );
1339            }
1340
1341            // We have to check to see that the inheritance rules have been applied before binding this mojo.
1342
if ( execution.isInheritanceApplied() || mojoDescriptor.isInheritedByDefault() )
1343            {
1344                MojoExecution mojoExecution = new MojoExecution( mojoDescriptor, execution.getId() );
1345
1346                String JavaDoc phase = execution.getPhase();
1347
1348                if ( phase == null )
1349                {
1350                    // if the phase was not in the configuration, use the phase in the descriptor
1351
phase = mojoDescriptor.getPhase();
1352                }
1353
1354                if ( phase != null )
1355                {
1356                    if ( mojoDescriptor.isDirectInvocationOnly() )
1357                    {
1358                        throw new LifecycleExecutionException( "Mojo: \'" + goal +
1359                            "\' requires direct invocation. It cannot be used as part of the lifecycle (it was included via the POM)." );
1360                    }
1361
1362                    addToLifecycleMappings( phaseMap, phase, mojoExecution, settings );
1363                }
1364            }
1365        }
1366    }
1367
1368    private void addToLifecycleMappings( Map JavaDoc lifecycleMappings, String JavaDoc phase, MojoExecution mojoExecution,
1369                                         Settings settings )
1370    {
1371        List JavaDoc goals = (List JavaDoc) lifecycleMappings.get( phase );
1372
1373        if ( goals == null )
1374        {
1375            goals = new ArrayList JavaDoc();
1376            lifecycleMappings.put( phase, goals );
1377        }
1378
1379        MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
1380        if ( settings.isOffline() && mojoDescriptor.isOnlineRequired() )
1381        {
1382            String JavaDoc goal = mojoDescriptor.getGoal();
1383            getLogger().warn( goal + " requires online mode, but maven is currently offline. Disabling " + goal + "." );
1384        }
1385        else
1386        {
1387            goals.add( mojoExecution );
1388        }
1389    }
1390
1391    private List JavaDoc processGoalChain( String JavaDoc task, Map JavaDoc phaseMap, Lifecycle lifecycle )
1392    {
1393        List JavaDoc goals = new ArrayList JavaDoc();
1394
1395        // only execute up to the given phase
1396
int index = lifecycle.getPhases().indexOf( task );
1397
1398        for ( int i = 0; i <= index; i++ )
1399        {
1400            String JavaDoc p = (String JavaDoc) lifecycle.getPhases().get( i );
1401
1402            List JavaDoc phaseGoals = (List JavaDoc) phaseMap.get( p );
1403
1404            if ( phaseGoals != null )
1405            {
1406                goals.addAll( phaseGoals );
1407            }
1408        }
1409        return goals;
1410    }
1411
1412    private MojoDescriptor getMojoDescriptor( String JavaDoc task, MavenSession session, MavenProject project,
1413                                              String JavaDoc invokedVia, boolean canUsePrefix, boolean isOptionalMojo )
1414        throws BuildFailureException, LifecycleExecutionException, PluginNotFoundException
1415    {
1416        String JavaDoc goal;
1417        Plugin plugin;
1418
1419        PluginDescriptor pluginDescriptor = null;
1420
1421        try
1422        {
1423            StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc( task, ":" );
1424            int numTokens = tok.countTokens();
1425
1426            if ( numTokens == 2 )
1427            {
1428                if ( !canUsePrefix )
1429                {
1430                    String JavaDoc msg = "Mapped-prefix lookup of mojos are only supported from direct invocation. " +
1431                        "Please use specification of the form groupId:artifactId[:version]:goal instead. " +
1432                        "(Offending mojo: \'" + task + "\', invoked via: \'" + invokedVia + "\')";
1433                    throw new LifecycleExecutionException( msg );
1434                }
1435
1436                String JavaDoc prefix = tok.nextToken();
1437                goal = tok.nextToken();
1438
1439                // Steps for retrieving the plugin model instance:
1440
// 1. request directly from the plugin collector by prefix
1441
pluginDescriptor = pluginManager.getPluginDescriptorForPrefix( prefix );
1442
1443                // 2. look in the repository via search groups
1444
if ( pluginDescriptor == null )
1445                {
1446                    plugin = pluginManager.getPluginDefinitionForPrefix( prefix, session, project );
1447                }
1448                else
1449                {
1450                    plugin = new Plugin();
1451
1452                    plugin.setGroupId( pluginDescriptor.getGroupId() );
1453                    plugin.setArtifactId( pluginDescriptor.getArtifactId() );
1454                    plugin.setVersion( pluginDescriptor.getVersion() );
1455                }
1456
1457                // 3. search plugins in the current POM
1458
if ( plugin == null )
1459                {
1460                    for ( Iterator JavaDoc i = project.getBuildPlugins().iterator(); i.hasNext(); )
1461                    {
1462                        Plugin buildPlugin = (Plugin) i.next();
1463
1464                        PluginDescriptor desc = verifyPlugin( buildPlugin, project, session.getSettings(), session
1465                            .getLocalRepository() );
1466                        if ( prefix.equals( desc.getGoalPrefix() ) )
1467                        {
1468                            plugin = buildPlugin;
1469                        }
1470                    }
1471                }
1472
1473                // 4. default to o.a.m.plugins and maven-<prefix>-plugin
1474
if ( plugin == null )
1475                {
1476                    plugin = new Plugin();
1477                    plugin.setGroupId( PluginDescriptor.getDefaultPluginGroupId() );
1478                    plugin.setArtifactId( PluginDescriptor.getDefaultPluginArtifactId( prefix ) );
1479                }
1480
1481                for ( Iterator JavaDoc i = project.getBuildPlugins().iterator(); i.hasNext(); )
1482                {
1483                    Plugin buildPlugin = (Plugin) i.next();
1484
1485                    if ( buildPlugin.getKey().equals( plugin.getKey() ) )
1486                    {
1487                        plugin = buildPlugin;
1488                        break;
1489                    }
1490                }
1491            }
1492            else if ( numTokens == 3 || numTokens == 4 )
1493            {
1494                plugin = new Plugin();
1495
1496                plugin.setGroupId( tok.nextToken() );
1497                plugin.setArtifactId( tok.nextToken() );
1498
1499                if ( numTokens == 4 )
1500                {
1501                    plugin.setVersion( tok.nextToken() );
1502                }
1503
1504                goal = tok.nextToken();
1505            }
1506            else
1507            {
1508                String JavaDoc message = "Invalid task '" + task + "': you must specify a valid lifecycle phase, or" +
1509                    " a goal in the format plugin:goal or pluginGroupId:pluginArtifactId:pluginVersion:goal";
1510                throw new BuildFailureException( message );
1511            }
1512
1513            project.injectPluginManagementInfo( plugin );
1514
1515            if ( pluginDescriptor == null )
1516            {
1517                pluginDescriptor = verifyPlugin( plugin, project, session.getSettings(), session.getLocalRepository() );
1518            }
1519
1520            // this has been simplified from the old code that injected the plugin management stuff, since
1521
// pluginManagement injection is now handled by the project method.
1522
project.addPlugin( plugin );
1523
1524            MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( goal );
1525            if ( mojoDescriptor == null )
1526            {
1527                if ( isOptionalMojo )
1528                {
1529                    getLogger().info( "Skipping missing optional mojo: " + task );
1530                }
1531                else
1532                {
1533                    throw new BuildFailureException( "Required goal not found: " + task );
1534                }
1535            }
1536
1537            return mojoDescriptor;
1538        }
1539        catch ( PluginNotFoundException e )
1540        {
1541            if ( isOptionalMojo )
1542            {
1543                getLogger().info( "Skipping missing optional mojo: " + task );
1544                getLogger().debug( "Mojo: " + task + " could not be found. Reason: " + e.getMessage(), e );
1545            }
1546            else
1547            {
1548                throw e;
1549            }
1550        }
1551
1552        return null;
1553    }
1554
1555    protected void line()
1556    {
1557        getLogger().info( "----------------------------------------------------------------------------" );
1558    }
1559
1560    public Map JavaDoc getPhaseToLifecycleMap()
1561        throws LifecycleExecutionException
1562    {
1563        if ( phaseToLifecycleMap == null )
1564        {
1565            phaseToLifecycleMap = new HashMap JavaDoc();
1566
1567            for ( Iterator JavaDoc i = lifecycles.iterator(); i.hasNext(); )
1568            {
1569                Lifecycle lifecycle = (Lifecycle) i.next();
1570
1571                for ( Iterator JavaDoc p = lifecycle.getPhases().iterator(); p.hasNext(); )
1572                {
1573                    String JavaDoc phase = (String JavaDoc) p.next();
1574
1575                    if ( phaseToLifecycleMap.containsKey( phase ) )
1576                    {
1577                        Lifecycle prevLifecycle = (Lifecycle) phaseToLifecycleMap.get( phase );
1578                        throw new LifecycleExecutionException( "Phase '" + phase +
1579                            "' is defined in more than one lifecycle: '" + lifecycle.getId() + "' and '" +
1580                            prevLifecycle.getId() + "'" );
1581                    }
1582                    else
1583                    {
1584                        phaseToLifecycleMap.put( phase, lifecycle );
1585                    }
1586                }
1587            }
1588        }
1589        return phaseToLifecycleMap;
1590    }
1591
1592    private static class TaskSegment
1593    {
1594        private boolean aggregate;
1595
1596        private List JavaDoc tasks = new ArrayList JavaDoc();
1597
1598        TaskSegment()
1599        {
1600
1601        }
1602
1603        TaskSegment( boolean aggregate )
1604        {
1605            this.aggregate = aggregate;
1606        }
1607
1608        public String JavaDoc toString()
1609        {
1610            StringBuffer JavaDoc message = new StringBuffer JavaDoc();
1611
1612            message.append( " task-segment: [" );
1613
1614            for ( Iterator JavaDoc it = tasks.iterator(); it.hasNext(); )
1615            {
1616                String JavaDoc task = (String JavaDoc) it.next();
1617
1618                message.append( task );
1619
1620                if ( it.hasNext() )
1621                {
1622                    message.append( ", " );
1623                }
1624            }
1625
1626            message.append( "]" );
1627
1628            if ( aggregate )
1629            {
1630                message.append( " (aggregator-style)" );
1631            }
1632
1633            return message.toString();
1634        }
1635
1636        boolean aggregate()
1637        {
1638            return aggregate;
1639        }
1640
1641        void add( String JavaDoc task )
1642        {
1643            tasks.add( task );
1644        }
1645
1646        List JavaDoc getTasks()
1647        {
1648            return tasks;
1649        }
1650    }
1651}
1652
Popular Tags