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