001package org.apache.maven.lifecycle.internal; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import java.util.List; 023import java.util.Map; 024 025import org.apache.maven.execution.ExecutionEvent; 026import org.apache.maven.execution.MavenExecutionResult; 027import org.apache.maven.execution.MavenSession; 028import org.apache.maven.lifecycle.DefaultLifecycles; 029import org.apache.maven.lifecycle.MissingProjectException; 030import org.apache.maven.lifecycle.NoGoalSpecifiedException; 031import org.apache.maven.lifecycle.internal.builder.Builder; 032import org.apache.maven.lifecycle.internal.builder.BuilderNotFoundException; 033import org.apache.maven.session.scope.internal.SessionScope; 034import org.codehaus.plexus.component.annotations.Component; 035import org.codehaus.plexus.component.annotations.Requirement; 036import org.codehaus.plexus.logging.Logger; 037 038/** 039 * Starts the build life cycle 040 * 041 * @author Jason van Zyl 042 * @author Benjamin Bentmann 043 * @author Kristian Rosenvold 044 */ 045@Component( role = LifecycleStarter.class ) 046public class LifecycleStarter 047{ 048 @Requirement 049 private ExecutionEventCatapult eventCatapult; 050 051 @Requirement 052 private DefaultLifecycles defaultLifeCycles; 053 054 @Requirement 055 private Logger logger; 056 057 @Requirement 058 private BuildListCalculator buildListCalculator; 059 060 @Requirement 061 private LifecycleDebugLogger lifecycleDebugLogger; 062 063 @Requirement 064 private LifecycleTaskSegmentCalculator lifecycleTaskSegmentCalculator; 065 066 @Requirement 067 private Map<String, Builder> builders; 068 069 @Requirement 070 private SessionScope sessionScope; 071 072 public void execute( MavenSession session ) 073 { 074 eventCatapult.fire( ExecutionEvent.Type.SessionStarted, session, null ); 075 076 ReactorContext reactorContext = null; 077 ProjectBuildList projectBuilds = null; 078 MavenExecutionResult result = session.getResult(); 079 080 try 081 { 082 if ( buildExecutionRequiresProject( session ) && projectIsNotPresent( session ) ) 083 { 084 throw new MissingProjectException( "The goal you specified requires a project to execute" 085 + " but there is no POM in this directory (" + session.getExecutionRootDirectory() + ")." 086 + " Please verify you invoked Maven from the correct directory." ); 087 } 088 089 List<TaskSegment> taskSegments = lifecycleTaskSegmentCalculator.calculateTaskSegments( session ); 090 projectBuilds = buildListCalculator.calculateProjectBuilds( session, taskSegments ); 091 092 if ( projectBuilds.isEmpty() ) 093 { 094 throw new NoGoalSpecifiedException( "No goals have been specified for this build." 095 + " You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or" 096 + " <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>." 097 + " Available lifecycle phases are: " + defaultLifeCycles.getLifecyclePhaseList() + "." ); 098 } 099 100 ProjectIndex projectIndex = new ProjectIndex( session.getProjects() ); 101 102 if ( logger.isDebugEnabled() ) 103 { 104 lifecycleDebugLogger.debugReactorPlan( projectBuilds ); 105 } 106 107 ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader(); 108 ReactorBuildStatus reactorBuildStatus = new ReactorBuildStatus( session.getProjectDependencyGraph() ); 109 reactorContext = 110 new ReactorContext( result, projectIndex, oldContextClassLoader, reactorBuildStatus, 111 sessionScope.memento() ); 112 113 String builderId = session.getRequest().getBuilderId(); 114 Builder builder = builders.get( builderId ); 115 if ( builder == null ) 116 { 117 throw new BuilderNotFoundException( String.format( "The builder requested using id = %s cannot be" 118 + " found", builderId ) ); 119 } 120 121 int degreeOfConcurrency = session.getRequest().getDegreeOfConcurrency(); 122 if ( degreeOfConcurrency >= 2 ) 123 { 124 logger.info( "" ); 125 logger.info( String.format( "Using the %s implementation with a thread count of %d", 126 builder.getClass().getSimpleName(), degreeOfConcurrency ) ); 127 } 128 builder.build( session, reactorContext, projectBuilds, taskSegments, reactorBuildStatus ); 129 130 } 131 catch ( Exception e ) 132 { 133 result.addException( e ); 134 } 135 finally 136 { 137 eventCatapult.fire( ExecutionEvent.Type.SessionEnded, session, null ); 138 } 139 } 140 141 private boolean buildExecutionRequiresProject( MavenSession session ) 142 { 143 return lifecycleTaskSegmentCalculator.requiresProject( session ); 144 } 145 146 private boolean projectIsNotPresent( MavenSession session ) 147 { 148 return !session.getRequest().isProjectPresent(); 149 } 150}