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