1 package org.apache.maven;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 import java.io.File;
24 import java.io.FileNotFoundException;
25 import java.io.IOException;
26 import java.text.DateFormat;
27 import java.text.SimpleDateFormat;
28 import java.util.ArrayList;
29 import java.util.Collections;
30 import java.util.Date;
31 import java.util.HashSet;
32 import java.util.Iterator;
33 import java.util.List;
34 import java.util.Properties;
35 import java.util.Set;
36 import java.util.TimeZone;
37
38 import org.apache.maven.artifact.manager.DefaultWagonManager;
39 import org.apache.maven.artifact.manager.WagonManager;
40 import org.apache.maven.artifact.repository.ArtifactRepository;
41 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
42 import org.apache.maven.artifact.resolver.ArtifactResolver;
43 import org.apache.maven.artifact.resolver.DefaultArtifactResolver;
44 import org.apache.maven.artifact.versioning.ArtifactVersion;
45 import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
46 import org.apache.maven.execution.BuildFailure;
47 import org.apache.maven.execution.DefaultMavenExecutionRequest;
48 import org.apache.maven.execution.MavenExecutionRequest;
49 import org.apache.maven.execution.MavenSession;
50 import org.apache.maven.execution.ReactorManager;
51 import org.apache.maven.execution.RuntimeInformation;
52 import org.apache.maven.lifecycle.LifecycleExecutionException;
53 import org.apache.maven.lifecycle.LifecycleExecutor;
54 import org.apache.maven.model.Profile;
55 import org.apache.maven.monitor.event.DefaultEventDispatcher;
56 import org.apache.maven.monitor.event.EventDispatcher;
57 import org.apache.maven.monitor.event.MavenEvents;
58 import org.apache.maven.profiles.ProfileManager;
59 import org.apache.maven.profiles.activation.ProfileActivationException;
60 import org.apache.maven.project.DuplicateProjectException;
61 import org.apache.maven.project.MavenProject;
62 import org.apache.maven.project.MavenProjectBuilder;
63 import org.apache.maven.project.MissingProjectException;
64 import org.apache.maven.project.ProjectBuildingException;
65 import org.apache.maven.reactor.MavenExecutionException;
66 import org.apache.maven.settings.Mirror;
67 import org.apache.maven.settings.Proxy;
68 import org.apache.maven.settings.Server;
69 import org.apache.maven.settings.Settings;
70 import org.apache.maven.usability.SystemWarnings;
71 import org.apache.maven.usability.diagnostics.ErrorDiagnostics;
72 import org.codehaus.plexus.PlexusConstants;
73 import org.codehaus.plexus.PlexusContainer;
74 import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
75 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
76 import org.codehaus.plexus.context.Context;
77 import org.codehaus.plexus.context.ContextException;
78 import org.codehaus.plexus.logging.AbstractLogEnabled;
79 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
80 import org.codehaus.plexus.util.FileUtils;
81 import org.codehaus.plexus.util.Os;
82 import org.codehaus.plexus.util.StringUtils;
83 import org.codehaus.plexus.util.dag.CycleDetectedException;
84 import org.codehaus.plexus.util.xml.Xpp3Dom;
85 import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;
86 import org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException;
87
88
89
90
91
92 public class DefaultMaven
93 extends AbstractLogEnabled
94 implements Maven, Contextualizable
95 {
96
97
98
99
100 protected MavenProjectBuilder projectBuilder;
101
102 protected LifecycleExecutor lifecycleExecutor;
103
104 protected PlexusContainer container;
105
106 protected ErrorDiagnostics errorDiagnostics;
107
108 protected RuntimeInformation runtimeInformation;
109
110 private static final long MB = 1024 * 1024;
111
112 private static final int MS_PER_SEC = 1000;
113
114 private static final int SEC_PER_MIN = 60;
115
116
117
118
119
120 public void execute( MavenExecutionRequest request )
121 throws MavenExecutionException
122 {
123
124
125
126
127
128 EventDispatcher dispatcher = request.getEventDispatcher();
129
130 String event = MavenEvents.REACTOR_EXECUTION;
131
132 dispatcher.dispatchStart( event, request.getBaseDirectory() );
133
134 ReactorManager rm;
135 try
136 {
137 rm = doExecute( request, dispatcher );
138 }
139 catch ( LifecycleExecutionException e )
140 {
141 dispatcher.dispatchError( event, request.getBaseDirectory(), e );
142
143 logError( e, request.isShowErrors() );
144
145 stats( request.getStartTime() );
146
147 line();
148
149 throw new MavenExecutionException( e.getMessage(), e );
150 }
151 catch ( BuildFailureException e )
152 {
153 dispatcher.dispatchError( event, request.getBaseDirectory(), e );
154
155 logFailure( e, request.isShowErrors() );
156
157 stats( request.getStartTime() );
158
159 line();
160
161 throw new MavenExecutionException( e.getMessage(), e );
162 }
163 catch ( Throwable t )
164 {
165 dispatcher.dispatchError( event, request.getBaseDirectory(), t );
166
167 logFatal( t );
168
169 stats( request.getStartTime() );
170
171 line();
172
173 throw new MavenExecutionException( "Error executing project within the reactor", t );
174 }
175
176
177
178
179 logReactorSummary( rm );
180
181 if ( rm.hasBuildFailures() )
182 {
183 logErrors( rm, request.isShowErrors() );
184
185 if ( !ReactorManager.FAIL_NEVER.equals( rm.getFailureBehavior() ) )
186 {
187 dispatcher.dispatchError( event, request.getBaseDirectory(), null );
188
189 getLogger().info( "BUILD ERRORS" );
190
191 line();
192
193 stats( request.getStartTime() );
194
195 line();
196
197 throw new MavenExecutionException( "Some builds failed" );
198 }
199 else
200 {
201 getLogger().info( " + Ignoring failures" );
202 }
203 }
204
205 logSuccess( rm );
206
207 stats( request.getStartTime() );
208
209 line();
210
211 dispatcher.dispatchEnd( event, request.getBaseDirectory() );
212 }
213
214 private void logErrors( ReactorManager rm, boolean showErrors )
215 {
216 for ( Iterator it = rm.getSortedProjects().iterator(); it.hasNext(); )
217 {
218 MavenProject project = (MavenProject) it.next();
219
220 if ( rm.hasBuildFailure( project ) )
221 {
222 BuildFailure buildFailure = rm.getBuildFailure( project );
223
224 getLogger().info(
225 "Error for project: " + project.getName() + " (during " + buildFailure.getTask() + ")" );
226
227 line();
228
229 logDiagnostics( buildFailure.getCause() );
230
231 logTrace( buildFailure.getCause(), showErrors );
232 }
233 }
234
235 if ( !showErrors )
236 {
237 getLogger().info( "For more information, run Maven with the -e switch" );
238
239 line();
240 }
241
242 }
243
244 private ReactorManager doExecute( MavenExecutionRequest request, EventDispatcher dispatcher )
245 throws MavenExecutionException, BuildFailureException, LifecycleExecutionException
246 {
247 if ( request.getSettings().isOffline() )
248 {
249 getLogger().info( SystemWarnings.getOfflineWarning() );
250
251 WagonManager wagonManager = null;
252
253 try
254 {
255 wagonManager = (WagonManager) container.lookup( WagonManager.ROLE );
256
257 wagonManager.setOnline( false );
258 }
259 catch ( ComponentLookupException e )
260 {
261 throw new MavenExecutionException( "Cannot retrieve WagonManager in order to set offline mode.", e );
262 }
263 finally
264 {
265 try
266 {
267 container.release( wagonManager );
268 }
269 catch ( ComponentLifecycleException e )
270 {
271 getLogger().warn( "Cannot release WagonManager.", e );
272 }
273 }
274 }
275
276 try
277 {
278 resolveParameters( request.getSettings(), request.getExecutionProperties() );
279 }
280 catch ( ComponentLookupException e )
281 {
282 throw new MavenExecutionException( "Unable to configure Maven for execution", e );
283 }
284 catch ( ComponentLifecycleException e )
285 {
286 throw new MavenExecutionException( "Unable to configure Maven for execution", e );
287 }
288 catch ( SettingsConfigurationException e )
289 {
290 throw new MavenExecutionException( "Unable to configure Maven for execution", e );
291 }
292
293 ProfileManager globalProfileManager = request.getGlobalProfileManager();
294
295 globalProfileManager.loadSettingsProfiles( request.getSettings() );
296
297 getLogger().info( "Scanning for projects..." );
298
299 boolean foundProjects = true;
300 List projects = getProjects( request );
301 if ( projects.isEmpty() )
302 {
303 projects.add( getSuperProject( request ) );
304 foundProjects = false;
305 }
306
307 ReactorManager rm;
308 try
309 {
310 String resumeFrom = request.getResumeFrom();
311
312 List projectList = request.getSelectedProjects();
313
314 String makeBehavior = request.getMakeBehavior();
315
316 rm = new ReactorManager( projects, projectList, resumeFrom, makeBehavior );
317
318 rm.setFailureBehavior( request.getFailureBehavior() );
319
320 }
321 catch ( CycleDetectedException e )
322 {
323 throw new BuildFailureException(
324 "The projects in the reactor contain a cyclic reference: " + e.getMessage(), e );
325 }
326 catch ( DuplicateProjectException e )
327 {
328 throw new BuildFailureException( e.getMessage(), e );
329 }
330 catch ( MissingProjectException e )
331 {
332 throw new BuildFailureException( e.getMessage(), e );
333 }
334
335
336
337
338
339 validateActivatedProfiles( globalProfileManager, projects );
340
341 if ( rm.hasMultipleProjects() )
342 {
343 getLogger().info( "Reactor build order: " );
344
345 for ( Iterator i = rm.getSortedProjects().iterator(); i.hasNext(); )
346 {
347 MavenProject project = (MavenProject) i.next();
348 getLogger().info( " " + project.getName() );
349 }
350 }
351
352 MavenSession session = createSession( request, rm );
353
354 session.setUsingPOMsFromFilesystem( foundProjects );
355
356 lifecycleExecutor.execute( session, rm, dispatcher );
357
358 return rm;
359 }
360
361 private void validateActivatedProfiles( ProfileManager globalProfileManager, List projects )
362 {
363 if ( globalProfileManager != null )
364 {
365
366 Set activeProfileIds = new HashSet();
367
368 for ( Iterator i = projects.iterator(); i.hasNext(); )
369 {
370 MavenProject project = (MavenProject) i.next();
371
372 do
373 {
374 for ( Iterator j = project.getActiveProfiles().iterator(); j.hasNext(); )
375 {
376 activeProfileIds.add( ( (Profile) j.next() ).getId() );
377 }
378 project = project.getParent();
379 }
380 while ( project != null );
381 }
382
383 for ( Iterator i = globalProfileManager.getExplicitlyActivatedIds().iterator(); i.hasNext(); )
384 {
385 String explicitProfileId = (String) i.next();
386
387 if ( !activeProfileIds.contains( explicitProfileId ) )
388 {
389 getLogger().warn( "\n\tProfile with id: \'" + explicitProfileId + "\' has not been activated.\n" );
390 }
391 }
392 }
393 }
394
395 private MavenProject getSuperProject( MavenExecutionRequest request )
396 throws MavenExecutionException
397 {
398 MavenProject superProject;
399 try
400 {
401 superProject = projectBuilder.buildStandaloneSuperProject( request.getLocalRepository(), request.getGlobalProfileManager() );
402
403 }
404 catch ( ProjectBuildingException e )
405 {
406 throw new MavenExecutionException( e.getMessage(), e );
407 }
408 return superProject;
409 }
410
411 private List getProjects( MavenExecutionRequest request )
412 throws MavenExecutionException, BuildFailureException
413 {
414 List projects;
415 try
416 {
417 List files = getProjectFiles( request );
418
419 projects = collectProjects( files, request, !request.isReactorActive() );
420
421 }
422 catch ( IOException e )
423 {
424 throw new MavenExecutionException( "Error processing projects for the reactor: " + e.getMessage(), e );
425 }
426 catch ( ArtifactResolutionException e )
427 {
428 throw new MavenExecutionException( e.getMessage(), e );
429 }
430 catch ( ProjectBuildingException e )
431 {
432 throw new MavenExecutionException( e.getMessage(), e );
433 }
434 catch ( ProfileActivationException e )
435 {
436 throw new MavenExecutionException( e.getMessage(), e );
437 }
438 return projects;
439 }
440
441 private void logReactorSummaryLine( String name, String status )
442 {
443 logReactorSummaryLine( name, status, -1 );
444 }
445
446 private void logReactorSummaryLine( String name, String status, long time )
447 {
448 StringBuffer messageBuffer = new StringBuffer();
449
450 messageBuffer.append( name );
451
452 int dotCount = 54;
453
454 dotCount -= name.length();
455
456 messageBuffer.append( " " );
457
458 for ( int i = 0; i < dotCount; i++ )
459 {
460 messageBuffer.append( '.' );
461 }
462
463 messageBuffer.append( " " );
464
465 messageBuffer.append( status );
466
467 if ( time >= 0 )
468 {
469 messageBuffer.append( " [" );
470
471 messageBuffer.append( getFormattedTime( time ) );
472
473 messageBuffer.append( "]" );
474 }
475
476 getLogger().info( messageBuffer.toString() );
477 }
478
479 private static String getFormattedTime( long time )
480 {
481 String pattern = "s.SSS's'";
482 if ( time / 60000L > 0 )
483 {
484 pattern = "m:s" + pattern;
485 if ( time / 3600000L > 0 )
486 {
487 pattern = "H:m" + pattern;
488 }
489 }
490 DateFormat fmt = new SimpleDateFormat( pattern );
491 fmt.setTimeZone( TimeZone.getTimeZone( "UTC" ) );
492 return fmt.format( new Date( time ) );
493 }
494
495 private List collectProjects( List files, MavenExecutionRequest request, boolean isRoot )
496 throws ArtifactResolutionException, ProjectBuildingException, ProfileActivationException,
497 MavenExecutionException, BuildFailureException
498 {
499
500
501 List projects = new ArrayList( files.size() );
502
503 for ( Iterator iterator = files.iterator(); iterator.hasNext(); )
504 {
505 File file = (File) iterator.next();
506
507 boolean usingReleasePom = false;
508
509 if ( RELEASE_POMv4.equals( file.getName() ) )
510 {
511 getLogger().info( "NOTE: Using release-pom: " + file + " in reactor build." );
512 usingReleasePom = true;
513 }
514
515 MavenProject project = getProject( file, request );
516
517 if ( isRoot )
518 {
519 project.setExecutionRoot( true );
520 }
521
522 if ( ( project.getPrerequisites() != null ) && ( project.getPrerequisites().getMaven() != null ) )
523 {
524 DefaultArtifactVersion version = new DefaultArtifactVersion( project.getPrerequisites().getMaven() );
525 if ( runtimeInformation.getApplicationVersion().compareTo( version ) < 0 )
526 {
527 throw new BuildFailureException( "Unable to build project '" + project.getFile() +
528 "; it requires Maven version " + version.toString() );
529 }
530 }
531
532 if ( ( project.getModules() != null ) && !project.getModules().isEmpty() && request.isRecursive() )
533 {
534
535 project.setPackaging( "pom" );
536
537 File basedir = file.getParentFile();
538
539
540 List moduleFiles = new ArrayList( project.getModules().size() );
541 for ( Iterator i = project.getModules().iterator(); i.hasNext(); )
542 {
543 String name = (String) i.next();
544
545 if ( StringUtils.isEmpty( StringUtils.trim( name ) ) )
546 {
547 getLogger().warn(
548 "Empty module detected. Please check you don't have any empty module definitions in your POM." );
549
550 continue;
551 }
552
553 File moduleFile = new File( basedir, name );
554
555 if ( moduleFile.exists() && moduleFile.isDirectory() )
556 {
557 if ( usingReleasePom )
558 {
559 moduleFile = new File( basedir, name + "/" + Maven.RELEASE_POMv4 );
560 }
561 else
562 {
563 moduleFile = new File( basedir, name + "/" + Maven.POMv4 );
564 }
565 }
566
567 if ( Os.isFamily( "windows" ) )
568 {
569
570
571 try
572 {
573 moduleFile = moduleFile.getCanonicalFile();
574 }
575 catch ( IOException e )
576 {
577 throw new MavenExecutionException( "Unable to canonicalize file name " + moduleFile, e );
578 }
579 }
580 else
581 {
582 moduleFile = new File( moduleFile.toURI().normalize() );
583 }
584
585 moduleFiles.add( moduleFile );
586 }
587
588 List collectedProjects =
589 collectProjects( moduleFiles, request, false );
590 projects.addAll( collectedProjects );
591 project.setCollectedProjects( collectedProjects );
592 }
593 projects.add( project );
594 }
595
596 return projects;
597 }
598
599
600
601
602 public MavenProject getProject( File pom, ArtifactRepository localRepository, Settings settings,
603 Properties userProperties, ProfileManager globalProfileManager )
604 throws ProjectBuildingException, ArtifactResolutionException, ProfileActivationException
605 {
606 MavenExecutionRequest request = new DefaultMavenExecutionRequest(
607 localRepository,
608 settings,
609 new DefaultEventDispatcher(),
610 Collections.EMPTY_LIST,
611 pom.getParentFile()
612 .getAbsolutePath(),
613 globalProfileManager,
614 globalProfileManager.getRequestProperties(),
615 new Properties(), false );
616
617 return getProject( pom, request );
618 }
619
620 public MavenProject getProject( File pom, MavenExecutionRequest request )
621 throws ProjectBuildingException, ArtifactResolutionException, ProfileActivationException
622 {
623 if ( pom.exists() )
624 {
625 if ( pom.length() == 0 )
626 {
627 throw new ProjectBuildingException( "unknown", "The file " + pom.getAbsolutePath() +
628 " you specified has zero length." );
629 }
630 }
631
632 return projectBuilder.build( pom, request.getProjectBuilderConfiguration() );
633 }
634
635
636
637
638
639
640
641
642
643
644 protected MavenSession createSession( MavenExecutionRequest request,
645 ReactorManager rpm )
646 {
647 return new MavenSession( container, request.getSettings(), request.getLocalRepository(),
648 request.getEventDispatcher(), rpm, request.getGoals(), request.getBaseDirectory(),
649 request.getExecutionProperties(), request.getUserProperties(), request.getStartTime() );
650 }
651
652
653
654
655
656
657
658 private void resolveParameters( Settings settings, Properties executionProperties )
659 throws ComponentLookupException, ComponentLifecycleException, SettingsConfigurationException
660 {
661
662 try
663 {
664 DefaultWagonManager wagonManager = (DefaultWagonManager) container.lookup( WagonManager.ROLE );
665
666 String oldUserAgent = wagonManager.getHttpUserAgent();
667 int firstSpace = oldUserAgent == null ? -1 : oldUserAgent.indexOf( " " );
668
669 StringBuffer buffer = new StringBuffer();
670
671 buffer.append( "Apache-Maven/" );
672
673 ArtifactVersion version = runtimeInformation.getApplicationVersion();
674 if ( version != null )
675 {
676 buffer.append( version.getMajorVersion() );
677 buffer.append( '.' );
678 buffer.append( version.getMinorVersion() );
679 }
680 else
681 {
682 buffer.append( "unknown" );
683 }
684
685 buffer.append( ' ' );
686 if ( firstSpace > -1 )
687 {
688 buffer.append( oldUserAgent.substring( firstSpace + 1 ) );
689 buffer.append( ' ' );
690 buffer.append( oldUserAgent.substring( 0, firstSpace ) );
691 }
692 else
693 {
694 buffer.append( oldUserAgent );
695 }
696
697 wagonManager.setHttpUserAgent( buffer.toString() );
698 }
699 catch ( ClassCastException e )
700 {
701
702 }
703
704 WagonManager wagonManager = (WagonManager) container.lookup( WagonManager.ROLE );
705
706 SecDispatcher sd = null;
707
708 try
709 {
710 Proxy proxy = settings.getActiveProxy();
711
712 try
713 {
714 sd = (SecDispatcher) container.lookup( SecDispatcher.ROLE, "maven" );
715 }
716 catch (Exception e)
717 {
718 getLogger().warn( "Security features are disabled. Cannot find plexus component "+SecDispatcher.ROLE + ":maven" );
719
720 line();
721 }
722
723 if ( proxy != null )
724 {
725 if ( proxy.getHost() == null )
726 {
727 throw new SettingsConfigurationException( "Proxy in settings.xml has no host" );
728 }
729
730 String pass = proxy.getPassword();
731
732 if ( sd != null )
733 {
734 try
735 {
736 pass = sd.decrypt( pass );
737 }
738 catch ( SecDispatcherException e )
739 {
740 reportSecurityConfigurationError( "password for proxy '" + proxy.getId() + "'", e );
741 }
742 }
743
744 wagonManager.addProxy( proxy.getProtocol(), proxy.getHost(), proxy.getPort(), proxy.getUsername(),
745 pass, proxy.getNonProxyHosts() );
746 }
747
748 for ( Iterator i = settings.getServers().iterator(); i.hasNext(); )
749 {
750 Server server = (Server) i.next();
751
752 String passWord = server.getPassword();
753
754 if ( sd != null )
755 {
756 try
757 {
758 passWord = sd.decrypt( passWord );
759 }
760 catch ( SecDispatcherException e )
761 {
762 reportSecurityConfigurationError( "password for server '" + server.getId() + "'", e );
763 }
764 }
765
766 String passPhrase = server.getPassphrase();
767
768 if ( sd != null )
769 {
770 try
771 {
772 passPhrase = sd.decrypt( passPhrase );
773 }
774 catch ( SecDispatcherException e )
775 {
776 reportSecurityConfigurationError( "passphrase for server '" + server.getId() + "'", e );
777 }
778 }
779
780 wagonManager.addAuthenticationInfo( server.getId(), server.getUsername(), passWord,
781 server.getPrivateKey(), passPhrase );
782
783 wagonManager.addPermissionInfo( server.getId(), server.getFilePermissions(),
784 server.getDirectoryPermissions() );
785
786 if ( server.getConfiguration() != null )
787 {
788 wagonManager.addConfiguration( server.getId(), (Xpp3Dom) server.getConfiguration() );
789 }
790 }
791
792 for ( Iterator i = settings.getMirrors().iterator(); i.hasNext(); )
793 {
794 Mirror mirror = (Mirror) i.next();
795
796 wagonManager.addMirror( mirror.getId(), mirror.getMirrorOf(), mirror.getUrl() );
797 }
798 }
799 finally
800 {
801 container.release( wagonManager );
802 if ( sd != null )
803 {
804 container.release( sd );
805 }
806 }
807
808
809 String numThreads = System.getProperty( "maven.artifact.threads" );
810 if ( numThreads != null )
811 {
812 int threads = 0;
813 try
814 {
815 threads = Integer.valueOf( numThreads ).intValue();
816
817 if ( threads < 1 )
818 {
819 getLogger().warn( "Invalid number of threads '" + threads + "' will be ignored" );
820 }
821 }
822 catch ( NumberFormatException e )
823 {
824 getLogger().warn( "Invalid number of threads '" + numThreads + "' will be ignored: " + e.getMessage() );
825 }
826
827 if ( threads > 0 )
828 {
829 DefaultArtifactResolver artifactResolver = (DefaultArtifactResolver) container.lookup( ArtifactResolver.ROLE );
830 try
831 {
832 artifactResolver.configureNumberOfThreads( threads );
833 getLogger().debug( "Resolution thread pool size set to: " + threads );
834 }
835 finally
836 {
837 container.release( artifactResolver );
838 }
839 }
840 }
841 }
842
843 private void reportSecurityConfigurationError( String affectedConfiguration, SecDispatcherException e )
844 {
845 Throwable cause = e;
846
847 String msg = "Not decrypting " + affectedConfiguration + " due to exception in security handler.";
848
849
850 while ( cause.getCause() != null )
851 {
852 cause = cause.getCause();
853 }
854
855
856 if ( cause instanceof FileNotFoundException )
857 {
858 msg += "\nEnsure that you have configured your master password file (and relocation if appropriate)\nSee the installation instructions for details.";
859 }
860
861 getLogger().warn( msg + "\nCause: " + cause.getMessage() );
862 getLogger().debug( "Full trace follows", e );
863 }
864
865
866
867
868
869 public void contextualize( Context context )
870 throws ContextException
871 {
872 container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
873 }
874
875
876
877
878
879 protected void logFatal( Throwable error )
880 {
881 line();
882
883 getLogger().error( "FATAL ERROR" );
884
885 line();
886
887 logDiagnostics( error );
888
889 logTrace( error, true );
890 }
891
892 protected void logError( Exception e, boolean showErrors )
893 {
894 line();
895
896 getLogger().error( "BUILD ERROR" );
897
898 line();
899
900 logDiagnostics( e );
901
902 logTrace( e, showErrors );
903
904 if ( !showErrors )
905 {
906 getLogger().info( "For more information, run Maven with the -e switch" );
907
908 line();
909 }
910 }
911
912 protected void logFailure( BuildFailureException e, boolean showErrors )
913 {
914 line();
915
916 getLogger().error( "BUILD FAILURE" );
917
918 line();
919
920 logDiagnostics( e );
921
922 logTrace( e, showErrors );
923
924 if ( !showErrors )
925 {
926 getLogger().info( "For more information, run Maven with the -e switch" );
927
928 line();
929 }
930 }
931
932 private void logTrace( Throwable t, boolean showErrors )
933 {
934 if ( getLogger().isDebugEnabled() )
935 {
936 getLogger().debug( "Trace", t );
937
938 line();
939 }
940 else if ( showErrors )
941 {
942 getLogger().info( "Trace", t );
943
944 line();
945 }
946 }
947
948 private void logDiagnostics( Throwable t )
949 {
950 String message = null;
951 if ( errorDiagnostics != null )
952 {
953 message = errorDiagnostics.diagnose( t );
954 }
955
956 if ( message == null )
957 {
958 message = t.getMessage();
959 }
960
961 getLogger().info( message );
962
963 line();
964 }
965
966 protected void logSuccess( ReactorManager rm )
967 {
968 line();
969
970 getLogger().info( "BUILD SUCCESSFUL" );
971
972 line();
973 }
974
975 private void logReactorSummary( ReactorManager rm )
976 {
977 if ( rm.hasMultipleProjects() && rm.executedMultipleProjects() )
978 {
979 getLogger().info( "" );
980 getLogger().info( "" );
981
982
983
984
985
986
987
988
989 line();
990 getLogger().info( "Reactor Summary:" );
991 line();
992
993 for ( Iterator it = rm.getSortedProjects().iterator(); it.hasNext(); )
994 {
995 MavenProject project = (MavenProject) it.next();
996
997 if ( rm.hasBuildFailure( project ) )
998 {
999 logReactorSummaryLine( project.getName(), "FAILED", rm.getBuildFailure( project ).getTime() );
1000 }
1001 else if ( rm.isBlackListed( project ) )
1002 {
1003 logReactorSummaryLine( project.getName(), "SKIPPED (dependency build failed or was skipped)" );
1004 }
1005 else if ( rm.hasBuildSuccess( project ) )
1006 {
1007 logReactorSummaryLine( project.getName(), "SUCCESS", rm.getBuildSuccess( project ).getTime() );
1008 }
1009 else
1010 {
1011 logReactorSummaryLine( project.getName(), "NOT BUILT" );
1012 }
1013 }
1014 line();
1015 }
1016 }
1017
1018 protected void stats( Date start )
1019 {
1020 Date finish = new Date();
1021
1022 long time = finish.getTime() - start.getTime();
1023
1024 getLogger().info( "Total time: " + formatTime( time ) );
1025
1026 getLogger().info( "Finished at: " + finish );
1027
1028
1029 System.gc();
1030
1031 Runtime r = Runtime.getRuntime();
1032
1033 getLogger().info(
1034 "Final Memory: " + ( r.totalMemory() - r.freeMemory() ) / MB + "M/" + r.totalMemory() / MB + "M" );
1035 }
1036
1037 protected void line()
1038 {
1039 getLogger().info( "------------------------------------------------------------------------" );
1040 }
1041
1042 protected static String formatTime( long ms )
1043 {
1044 long secs = ms / MS_PER_SEC;
1045
1046 long min = secs / SEC_PER_MIN;
1047
1048 secs = secs % SEC_PER_MIN;
1049
1050 String msg = "";
1051
1052 if ( min > 1 )
1053 {
1054 msg = min + " minutes ";
1055 }
1056 else if ( min == 1 )
1057 {
1058 msg = "1 minute ";
1059 }
1060
1061 if ( secs > 1 )
1062 {
1063 msg += secs + " seconds";
1064 }
1065 else if ( secs == 1 )
1066 {
1067 msg += "1 second";
1068 }
1069 else if ( min == 0 )
1070 {
1071 msg += "< 1 second";
1072 }
1073 return msg;
1074 }
1075
1076 private List getProjectFiles( MavenExecutionRequest request )
1077 throws IOException
1078 {
1079 List files = Collections.EMPTY_LIST;
1080
1081 File userDir = new File( System.getProperty( "user.dir" ) );
1082 if ( request.isReactorActive() )
1083 {
1084
1085
1086
1087
1088 String includes = System.getProperty( "maven.reactor.includes", "**/" + POMv4 + ",**/" + RELEASE_POMv4 );
1089 String excludes = System.getProperty( "maven.reactor.excludes", POMv4 + "," + RELEASE_POMv4 );
1090
1091 files = FileUtils.getFiles( userDir, includes, excludes );
1092
1093 filterOneProjectFilePerDirectory( files );
1094
1095
1096 Collections.sort( files );
1097 }
1098 else if ( request.getPomFile() != null )
1099 {
1100 File projectFile = new File( request.getPomFile() ).getAbsoluteFile();
1101
1102 if ( projectFile.exists() )
1103 {
1104 files = Collections.singletonList( projectFile );
1105 }
1106 }
1107 else
1108 {
1109 File projectFile = new File( userDir, RELEASE_POMv4 );
1110
1111 if ( !projectFile.exists() )
1112 {
1113 projectFile = new File( userDir, POMv4 );
1114 }
1115
1116 if ( projectFile.exists() )
1117 {
1118 files = Collections.singletonList( projectFile );
1119 }
1120 }
1121
1122 return files;
1123 }
1124
1125 private void filterOneProjectFilePerDirectory( List files )
1126 {
1127 List releaseDirs = new ArrayList();
1128
1129 for ( Iterator it = files.iterator(); it.hasNext(); )
1130 {
1131 File projectFile = (File) it.next();
1132
1133 if ( RELEASE_POMv4.equals( projectFile.getName() ) )
1134 {
1135 releaseDirs.add( projectFile.getParentFile() );
1136 }
1137 }
1138
1139 for ( Iterator it = files.iterator(); it.hasNext(); )
1140 {
1141 File projectFile = (File) it.next();
1142
1143
1144 if ( !RELEASE_POMv4.equals( projectFile.getName() ) && releaseDirs.contains( projectFile.getParentFile() ) )
1145 {
1146 it.remove();
1147 }
1148 }
1149 }
1150 }