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.HashSet; 023import java.util.List; 024 025import org.apache.maven.artifact.Artifact; 026import org.apache.maven.execution.BuildSuccess; 027import org.apache.maven.execution.ExecutionEvent; 028import org.apache.maven.execution.MavenSession; 029import org.apache.maven.execution.ProjectExecutionEvent; 030import org.apache.maven.execution.ProjectExecutionListener; 031import org.apache.maven.lifecycle.MavenExecutionPlan; 032import org.apache.maven.lifecycle.internal.builder.BuilderCommon; 033import org.apache.maven.plugin.MojoExecution; 034import org.apache.maven.project.MavenProject; 035import org.apache.maven.session.scope.internal.SessionScope; 036import org.codehaus.plexus.component.annotations.Component; 037import org.codehaus.plexus.component.annotations.Requirement; 038 039/** 040 * Builds one or more lifecycles for a full module 041 * 042 * @since 3.0 043 * @author Benjamin Bentmann 044 * @author Jason van Zyl 045 * @author Kristian Rosenvold (extracted class) 046 * <p/> 047 * NOTE: This class is not part of any public api and can be changed or deleted without prior notice. 048 */ 049@Component( role = LifecycleModuleBuilder.class ) 050public class LifecycleModuleBuilder 051{ 052 053 @Requirement 054 private MojoExecutor mojoExecutor; 055 056 @Requirement 057 private BuilderCommon builderCommon; 058 059 @Requirement 060 private ExecutionEventCatapult eventCatapult; 061 062 private ProjectExecutionListener projectExecutionListener; 063 064 // this tricks plexus-component-metadata generate required metadata 065 @Requirement 066 private List<ProjectExecutionListener> projectExecutionListeners; 067 068 @Requirement 069 private SessionScope sessionScope; 070 071 public void setProjectExecutionListeners( final List<ProjectExecutionListener> listeners ) 072 { 073 this.projectExecutionListeners = listeners; 074 this.projectExecutionListener = new CompoundProjectExecutionListener( listeners ); 075 } 076 077 public void buildProject( MavenSession session, ReactorContext reactorContext, MavenProject currentProject, 078 TaskSegment taskSegment ) 079 { 080 buildProject( session, session, reactorContext, currentProject, taskSegment ); 081 } 082 083 public void buildProject( MavenSession session, MavenSession rootSession, ReactorContext reactorContext, 084 MavenProject currentProject, TaskSegment taskSegment ) 085 { 086 session.setCurrentProject( currentProject ); 087 088 long buildStartTime = System.currentTimeMillis(); 089 090 // session may be different from rootSession seeded in DefaultMaven 091 // explicitly seed the right session here to make sure it is used by Guice 092 sessionScope.enter( reactorContext.getSessionScopeMemento() ); 093 sessionScope.seed( MavenSession.class, session ); 094 try 095 { 096 097 if ( reactorContext.getReactorBuildStatus().isHaltedOrBlacklisted( currentProject ) ) 098 { 099 eventCatapult.fire( ExecutionEvent.Type.ProjectSkipped, session, null ); 100 return; 101 } 102 103 BuilderCommon.attachToThread( currentProject ); 104 105 projectExecutionListener.beforeProjectExecution( new ProjectExecutionEvent( session, currentProject ) ); 106 107 eventCatapult.fire( ExecutionEvent.Type.ProjectStarted, session, null ); 108 109 MavenExecutionPlan executionPlan = 110 builderCommon.resolveBuildPlan( session, currentProject, taskSegment, new HashSet<Artifact>() ); 111 List<MojoExecution> mojoExecutions = executionPlan.getMojoExecutions(); 112 113 projectExecutionListener.beforeProjectLifecycleExecution( new ProjectExecutionEvent( session, 114 currentProject, 115 mojoExecutions ) ); 116 mojoExecutor.execute( session, mojoExecutions, reactorContext.getProjectIndex() ); 117 118 long buildEndTime = System.currentTimeMillis(); 119 120 projectExecutionListener.afterProjectExecutionSuccess( new ProjectExecutionEvent( session, currentProject, 121 mojoExecutions ) ); 122 123 reactorContext.getResult().addBuildSummary( new BuildSuccess( currentProject, 124 buildEndTime - buildStartTime ) ); 125 126 eventCatapult.fire( ExecutionEvent.Type.ProjectSucceeded, session, null ); 127 } 128 catch ( Throwable t ) 129 { 130 builderCommon.handleBuildError( reactorContext, rootSession, session, currentProject, t, buildStartTime ); 131 132 projectExecutionListener.afterProjectExecutionFailure( new ProjectExecutionEvent( session, currentProject, 133 t ) ); 134 135 // rethrow original errors and runtime exceptions 136 if ( t instanceof RuntimeException ) 137 { 138 throw (RuntimeException) t; 139 } 140 if ( t instanceof Error ) 141 { 142 throw (Error) t; 143 } 144 } 145 finally 146 { 147 sessionScope.exit(); 148 149 session.setCurrentProject( null ); 150 151 Thread.currentThread().setContextClassLoader( reactorContext.getOriginalContextClassLoader() ); 152 } 153 } 154}