View Javadoc
1   package org.apache.maven.lifecycle.internal;
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  import java.util.List;
23  import java.util.Map;
24  
25  import javax.inject.Inject;
26  import javax.inject.Named;
27  import javax.inject.Singleton;
28  
29  import org.apache.maven.execution.ExecutionEvent;
30  import org.apache.maven.execution.MavenExecutionResult;
31  import org.apache.maven.execution.MavenSession;
32  import org.apache.maven.lifecycle.DefaultLifecycles;
33  import org.apache.maven.lifecycle.MissingProjectException;
34  import org.apache.maven.lifecycle.NoGoalSpecifiedException;
35  import org.apache.maven.lifecycle.internal.builder.Builder;
36  import org.apache.maven.lifecycle.internal.builder.BuilderNotFoundException;
37  import org.apache.maven.session.scope.internal.SessionScope;
38  import org.slf4j.Logger;
39  import org.slf4j.LoggerFactory;
40  
41  /**
42   * Starts the build life cycle
43   *
44   * @author Jason van Zyl
45   * @author Benjamin Bentmann
46   * @author Kristian Rosenvold
47   */
48  @Named
49  @Singleton
50  public class LifecycleStarter
51  {
52      private final Logger logger = LoggerFactory.getLogger( getClass() );
53  
54      private final ExecutionEventCatapult eventCatapult;
55  
56      private final DefaultLifecycles defaultLifeCycles;
57  
58      private final BuildListCalculator buildListCalculator;
59  
60      private final LifecycleDebugLogger lifecycleDebugLogger;
61  
62      private final LifecycleTaskSegmentCalculator lifecycleTaskSegmentCalculator;
63  
64      private final Map<String, Builder> builders;
65  
66      private final SessionScope sessionScope;
67  
68      @Inject
69      public LifecycleStarter(
70              ExecutionEventCatapult eventCatapult,
71              DefaultLifecycles defaultLifeCycles,
72              BuildListCalculator buildListCalculator,
73              LifecycleDebugLogger lifecycleDebugLogger,
74              LifecycleTaskSegmentCalculator lifecycleTaskSegmentCalculator,
75              Map<String, Builder> builders,
76              SessionScope sessionScope )
77      {
78          this.eventCatapult = eventCatapult;
79          this.defaultLifeCycles = defaultLifeCycles;
80          this.buildListCalculator = buildListCalculator;
81          this.lifecycleDebugLogger = lifecycleDebugLogger;
82          this.lifecycleTaskSegmentCalculator = lifecycleTaskSegmentCalculator;
83          this.builders = builders;
84          this.sessionScope = sessionScope;
85      }
86  
87      public void execute( MavenSession session )
88      {
89          eventCatapult.fire( ExecutionEvent.Type.SessionStarted, session, null );
90  
91          ReactorContext reactorContext = null;
92          ProjectBuildList projectBuilds = null;
93          MavenExecutionResult result = session.getResult();
94  
95          try
96          {
97              if ( buildExecutionRequiresProject( session ) && projectIsNotPresent( session ) )
98              {
99                  throw new MissingProjectException( "The goal you specified requires a project to execute"
100                     + " but there is no POM in this directory (" + session.getExecutionRootDirectory() + ")."
101                     + " Please verify you invoked Maven from the correct directory." );
102             }
103 
104             List<TaskSegment> taskSegments = lifecycleTaskSegmentCalculator.calculateTaskSegments( session );
105             projectBuilds = buildListCalculator.calculateProjectBuilds( session, taskSegments );
106 
107             if ( projectBuilds.isEmpty() )
108             {
109                 throw new NoGoalSpecifiedException( "No goals have been specified for this build."
110                     + " You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or"
111                     + " <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>."
112                     + " Available lifecycle phases are: " + defaultLifeCycles.getLifecyclePhaseList() + "." );
113             }
114 
115             ProjectIndex projectIndex = new ProjectIndex( session.getProjects() );
116 
117             if ( logger.isDebugEnabled() )
118             {
119                 lifecycleDebugLogger.debugReactorPlan( projectBuilds );
120             }
121 
122             ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
123             ReactorBuildStatus reactorBuildStatus = new ReactorBuildStatus( session.getProjectDependencyGraph() );
124             reactorContext = new ReactorContext( result, projectIndex, oldContextClassLoader, reactorBuildStatus );
125 
126             String builderId = session.getRequest().getBuilderId();
127             Builder builder = builders.get( builderId );
128             if ( builder == null )
129             {
130                 throw new BuilderNotFoundException( String.format( "The builder requested using id = %s cannot be"
131                     + " found", builderId ) );
132             }
133 
134             int degreeOfConcurrency = session.getRequest().getDegreeOfConcurrency();
135             if ( degreeOfConcurrency > 1 )
136             {
137                 logger.info( "" );
138                 logger.info( String.format( "Using the %s implementation with a thread count of %d",
139                                             builder.getClass().getSimpleName(), degreeOfConcurrency ) );
140             }
141             builder.build( session, reactorContext, projectBuilds, taskSegments, reactorBuildStatus );
142 
143         }
144         catch ( Exception e )
145         {
146             result.addException( e );
147         }
148         finally
149         {
150             eventCatapult.fire( ExecutionEvent.Type.SessionEnded, session, null );
151         }
152     }
153 
154     private boolean buildExecutionRequiresProject( MavenSession session )
155     {
156         return lifecycleTaskSegmentCalculator.requiresProject( session );
157     }
158 
159     private boolean projectIsNotPresent( MavenSession session )
160     {
161         return !session.getRequest().isProjectPresent();
162     }
163 }