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