View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.lifecycle.internal;
20  
21  import java.util.List;
22  import java.util.Map;
23  
24  import org.apache.maven.execution.ExecutionEvent;
25  import org.apache.maven.execution.MavenExecutionResult;
26  import org.apache.maven.execution.MavenSession;
27  import org.apache.maven.lifecycle.DefaultLifecycles;
28  import org.apache.maven.lifecycle.MissingProjectException;
29  import org.apache.maven.lifecycle.NoGoalSpecifiedException;
30  import org.apache.maven.lifecycle.internal.builder.Builder;
31  import org.apache.maven.lifecycle.internal.builder.BuilderNotFoundException;
32  import org.apache.maven.session.scope.internal.SessionScope;
33  import org.codehaus.plexus.component.annotations.Component;
34  import org.codehaus.plexus.component.annotations.Requirement;
35  import org.codehaus.plexus.logging.Logger;
36  
37  /**
38   * Starts the build life cycle
39   *
40   * @author Jason van Zyl
41   * @author Benjamin Bentmann
42   * @author Kristian Rosenvold
43   */
44  @Component(role = LifecycleStarter.class)
45  public class LifecycleStarter {
46      @Requirement
47      private ExecutionEventCatapult eventCatapult;
48  
49      @Requirement
50      private DefaultLifecycles defaultLifeCycles;
51  
52      @Requirement
53      private Logger logger;
54  
55      @Requirement
56      private BuildListCalculator buildListCalculator;
57  
58      @Requirement
59      private LifecycleDebugLogger lifecycleDebugLogger;
60  
61      @Requirement
62      private LifecycleTaskSegmentCalculator lifecycleTaskSegmentCalculator;
63  
64      @Requirement
65      private Map<String, Builder> builders;
66  
67      @Requirement
68      private SessionScope sessionScope;
69  
70      public void execute(MavenSession session) {
71          eventCatapult.fire(ExecutionEvent.Type.SessionStarted, session, null);
72  
73          ReactorContext reactorContext = null;
74          ProjectBuildList projectBuilds = null;
75          MavenExecutionResult result = session.getResult();
76  
77          try {
78              if (buildExecutionRequiresProject(session) && projectIsNotPresent(session)) {
79                  throw new MissingProjectException("The goal you specified requires a project to execute"
80                          + " but there is no POM in this directory (" + session.getExecutionRootDirectory() + ")."
81                          + " Please verify you invoked Maven from the correct directory.");
82              }
83  
84              List<TaskSegment> taskSegments = lifecycleTaskSegmentCalculator.calculateTaskSegments(session);
85              projectBuilds = buildListCalculator.calculateProjectBuilds(session, taskSegments);
86  
87              if (projectBuilds.isEmpty()) {
88                  throw new NoGoalSpecifiedException("No goals have been specified for this build."
89                          + " You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or"
90                          + " <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>."
91                          + " Available lifecycle phases are: " + defaultLifeCycles.getLifecyclePhaseList() + ".");
92              }
93  
94              ProjectIndex projectIndex = new ProjectIndex(session.getProjects());
95  
96              if (logger.isDebugEnabled()) {
97                  lifecycleDebugLogger.debugReactorPlan(projectBuilds);
98              }
99  
100             ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
101             ReactorBuildStatus reactorBuildStatus = new ReactorBuildStatus(session.getProjectDependencyGraph());
102             reactorContext = new ReactorContext(result, projectIndex, oldContextClassLoader, reactorBuildStatus);
103 
104             String builderId = session.getRequest().getBuilderId();
105             Builder builder = builders.get(builderId);
106             if (builder == null) {
107                 throw new BuilderNotFoundException(
108                         String.format("The builder requested using id = %s cannot be" + " found", builderId));
109             }
110 
111             int degreeOfConcurrency = session.getRequest().getDegreeOfConcurrency();
112             if (degreeOfConcurrency > 1) {
113                 logger.info("");
114                 logger.info(String.format(
115                         "Using the %s implementation with a thread count of %d",
116                         builder.getClass().getSimpleName(), degreeOfConcurrency));
117             }
118             builder.build(session, reactorContext, projectBuilds, taskSegments, reactorBuildStatus);
119 
120         } catch (Exception e) {
121             result.addException(e);
122         } finally {
123             eventCatapult.fire(ExecutionEvent.Type.SessionEnded, session, null);
124         }
125     }
126 
127     private boolean buildExecutionRequiresProject(MavenSession session) {
128         return lifecycleTaskSegmentCalculator.requiresProject(session);
129     }
130 
131     private boolean projectIsNotPresent(MavenSession session) {
132         return !session.getRequest().isProjectPresent();
133     }
134 }