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