Replaced old build-plan mess with a single recursive plan instance that tracks direct invocation forks as well as lifecycle forks. All unit tests run, and I'm running integration tests now, to see if this fixes it0013.

git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@541938 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
John Dennis Casey 2007-05-26 21:06:12 +00:00
parent 4c3d71313b
commit 10febbbda0
33 changed files with 1104 additions and 2018 deletions

View File

@ -143,5 +143,11 @@ under the License.
<artifactId>plexus-active-collections</artifactId>
<version>1.0-beta-1</version>
</dependency>
<dependency>
<groupId>easymock</groupId>
<artifactId>easymock</artifactId>
<version>1.2_Java1.3</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -28,7 +28,6 @@ import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException
import org.apache.maven.context.BuildContextManager;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.execution.ReactorManager;
import org.apache.maven.lifecycle.binding.LifecycleBindingManager;
import org.apache.maven.lifecycle.binding.MojoBindingFactory;
import org.apache.maven.lifecycle.model.MojoBinding;
import org.apache.maven.lifecycle.plan.BuildPlan;
@ -63,34 +62,31 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;
/**
* @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id: DefaultLifecycleExecutor.java,v 1.16 2005/03/04 09:04:25
* jdcasey Exp $
* @todo because of aggregation, we ended up with cli-ish stuff in here (like line() and the project logging, without much of the event handling)
* @version $Id$
* @todo because of aggregation, we ended up with cli-ish stuff in here (like line() and the project logging, without
* much of the event handling)
*/
public class DefaultLifecycleExecutor
extends AbstractLogEnabled
implements LifecycleExecutor
public class DefaultLifecycleExecutor extends AbstractLogEnabled implements LifecycleExecutor
{
// ----------------------------------------------------------------------
// Components
// ----------------------------------------------------------------------
private PluginManager pluginManager;
private PluginLoader pluginLoader;
private BuildPlanner buildPlanner;
private ArtifactHandlerManager artifactHandlerManager;
private MojoBindingFactory mojoBindingFactory;
private LifecycleBindingManager lifecycleBindingManager;
private BuildContextManager buildContextManager;
// ----------------------------------------------------------------------
@ -98,14 +94,13 @@ public class DefaultLifecycleExecutor
// ----------------------------------------------------------------------
/**
* Execute a task. Each task may be a phase in the lifecycle or the
* execution of a mojo.
*
* Execute a task. Each task may be a phase in the lifecycle or the execution of a mojo.
*
* @param session
* @param rm
* @param dispatcher
*/
public void execute( MavenSession session, ReactorManager rm, EventDispatcher dispatcher )
public void execute( final MavenSession session, final ReactorManager rm, final EventDispatcher dispatcher )
throws BuildFailureException, LifecycleExecutionException
{
// TODO: This is dangerous, particularly when it's just a collection of loose-leaf projects being built
@ -114,7 +109,7 @@ public class DefaultLifecycleExecutor
List goals = session.getGoals();
if ( goals.isEmpty() && rootProject != null )
if ( goals.isEmpty() && ( rootProject != null ) )
{
String goal = rootProject.getDefaultGoal();
@ -146,8 +141,8 @@ public class DefaultLifecycleExecutor
executeTaskSegments( taskSegments, rm, session, rootProject, dispatcher );
}
private void executeTaskSegments( List taskSegments, ReactorManager rm, MavenSession session,
MavenProject rootProject, EventDispatcher dispatcher )
private void executeTaskSegments( final List taskSegments, final ReactorManager rm, final MavenSession session,
final MavenProject rootProject, final EventDispatcher dispatcher )
throws LifecycleExecutionException, BuildFailureException
{
for ( Iterator it = taskSegments.iterator(); it.hasNext(); )
@ -165,11 +160,11 @@ public class DefaultLifecycleExecutor
getLogger().info( " " + segment );
line();
String target = rootProject.getId() + " ( " + segment + " )";
getLogger().debug( "Constructing build plan for " + target );
// !! This is ripe for refactoring to an aspect.
// Event monitoring.
String event = MavenEvents.PROJECT_EXECUTION;
@ -183,23 +178,22 @@ public class DefaultLifecycleExecutor
// for the fork being executed, plus a stack of projects used in the ancestor execution contexts.
LifecycleExecutionContext ctx = new LifecycleExecutionContext( rootProject );
ctx.store( buildContextManager );
// NEW: Build up the execution plan, including configuration.
List mojoBindings = getLifecycleBindings( segment.getTasks(), rootProject, target );
// NEW: Then, iterate over each binding in that plan, and execute the associated mojo.
// only call once, with the top-level project (assumed to be provided as a parameter)...
for ( Iterator mojoIterator = mojoBindings.iterator(); mojoIterator.hasNext(); )
{
MojoBinding binding = (MojoBinding) mojoIterator.next();
executeGoalAndHandleFailures( binding, session, dispatcher, event, rm, buildStartTime,
target );
executeGoalAndHandleFailures( binding, session, dispatcher, event, rm, buildStartTime, target );
}
// clean up the execution context, so we don't pollute for future project-executions.
LifecycleExecutionContext.delete( buildContextManager );
rm.registerBuildSuccess( rootProject, System.currentTimeMillis() - buildStartTime );
dispatcher.dispatchEnd( event, target );
@ -212,8 +206,7 @@ public class DefaultLifecycleExecutor
getLogger().info( " " + segment );
getLogger().info(
"This project has been banned from further executions due to previous failures." );
getLogger().info( "This project has been banned from further executions due to previous failures." );
line();
}
@ -238,7 +231,7 @@ public class DefaultLifecycleExecutor
line();
String target = currentProject.getId() + " ( " + segment + " )";
// !! This is ripe for refactoring to an aspect.
// Event monitoring.
String event = MavenEvents.PROJECT_EXECUTION;
@ -246,23 +239,25 @@ public class DefaultLifecycleExecutor
long buildStartTime = System.currentTimeMillis();
dispatcher.dispatchStart( event, target );
LifecycleExecutionContext ctx = new LifecycleExecutionContext( currentProject );
ctx.store( buildContextManager );
List mojoBindings = getLifecycleBindings( segment.getTasks(), currentProject, target );
for ( Iterator mojoIterator = mojoBindings.iterator(); mojoIterator.hasNext(); )
{
MojoBinding mojoBinding = (MojoBinding) mojoIterator.next();
getLogger().debug( "Mojo: " + mojoBinding.getGoal() + " has config:\n" + mojoBinding.getConfiguration() );
executeGoalAndHandleFailures( mojoBinding, session, dispatcher, event, rm,
buildStartTime, target );
getLogger().debug(
"Mojo: " + mojoBinding.getGoal() + " has config:\n"
+ mojoBinding.getConfiguration() );
executeGoalAndHandleFailures( mojoBinding, session, dispatcher, event, rm, buildStartTime,
target );
}
LifecycleExecutionContext.delete( buildContextManager );
rm.registerBuildSuccess( currentProject, System.currentTimeMillis() - buildStartTime );
dispatcher.dispatchEnd( event, target );
@ -276,7 +271,7 @@ public class DefaultLifecycleExecutor
getLogger().info( " " + segment );
getLogger().info(
"This project has been banned from further executions due to previous failures." );
"This project has been banned from further executions due to previous failures." );
line();
}
@ -286,43 +281,43 @@ public class DefaultLifecycleExecutor
}
/**
* Retrieves the build plan for the current project, given the specified list of tasks. This
* build plan will consist of MojoBindings, each fully configured to execute, which enables us
* to enumerate the full build plan to the debug log-level, complete with the configuration each
* mojo will use.
* Retrieves the build plan for the current project, given the specified list of tasks. This build plan will consist
* of MojoBindings, each fully configured to execute, which enables us to enumerate the full build plan to the debug
* log-level, complete with the configuration each mojo will use.
*/
private List getLifecycleBindings( List tasks, MavenProject project, String targetDescription )
private List getLifecycleBindings( final List tasks, final MavenProject project, final String targetDescription )
throws LifecycleExecutionException
{
List mojoBindings;
try
{
BuildPlan plan = buildPlanner.constructBuildPlan( tasks, project );
if ( getLogger().isDebugEnabled() )
{
getLogger().debug( "\n\nOur build plan is:\n" + BuildPlanUtils.listBuildPlan( plan, project, lifecycleBindingManager, false ) + "\n\n" );
getLogger().debug( "\n\nOur build plan is:\n" + BuildPlanUtils.listBuildPlan( plan, false ) + "\n\n" );
}
mojoBindings = plan.getPlanMojoBindings( project, lifecycleBindingManager );
mojoBindings = plan.renderExecutionPlan( new Stack() );
}
catch ( LifecycleException e )
{
throw new LifecycleExecutionException( "Failed to construct build plan for: " + targetDescription + ". Reason: "
+ e.getMessage(), e );
throw new LifecycleExecutionException( "Failed to construct build plan for: " + targetDescription
+ ". Reason: " + e.getMessage(), e );
}
return mojoBindings;
}
private void executeGoalAndHandleFailures( MojoBinding mojoBinding, MavenSession session, EventDispatcher dispatcher, String event, ReactorManager rm,
long buildStartTime, String target )
private void executeGoalAndHandleFailures( final MojoBinding mojoBinding, final MavenSession session,
final EventDispatcher dispatcher, final String event,
final ReactorManager rm, final long buildStartTime, final String target )
throws BuildFailureException, LifecycleExecutionException
{
// NEW: Retrieve/use the current project stored in the execution context, for consistency.
LifecycleExecutionContext ctx = LifecycleExecutionContext.read( buildContextManager );
MavenProject project = ctx.getCurrentProject();
// NEW: Since the MojoBinding instances are configured when the build plan is constructed,
// all that remains to be done here is to load the PluginDescriptor, construct a MojoExecution
// instance, and call PluginManager.executeMojo( execution ). The MojoExecutor is constructed
@ -342,16 +337,16 @@ public class DefaultLifecycleExecutor
}
else
{
throw new LifecycleExecutionException( "Failed to load plugin for: " + MojoBindingUtils.toString( mojoBinding )
+ ". Reason: " + e.getMessage(), e );
throw new LifecycleExecutionException( "Failed to load plugin for: "
+ MojoBindingUtils.toString( mojoBinding ) + ". Reason: " + e.getMessage(), e );
}
}
if ( pluginDescriptor != null )
{
MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( mojoBinding.getGoal() );
MojoExecution mojoExecution = new MojoExecution( mojoDescriptor );
mojoExecution.setConfiguration( (Xpp3Dom) mojoBinding.getConfiguration() );
try
@ -360,8 +355,8 @@ public class DefaultLifecycleExecutor
}
catch ( PluginManagerException e )
{
throw new LifecycleExecutionException( "Internal error in the plugin manager executing goal '" +
mojoDescriptor.getId() + "': " + e.getMessage(), e );
throw new LifecycleExecutionException( "Internal error in the plugin manager executing goal '"
+ mojoDescriptor.getId() + "': " + e.getMessage(), e );
}
catch ( ArtifactNotFoundException e )
{
@ -390,8 +385,8 @@ public class DefaultLifecycleExecutor
}
else
{
throw new LifecycleExecutionException( "Failed to load plugin for: " + MojoBindingUtils.toString( mojoBinding )
+ ". Reason: unknown" );
throw new LifecycleExecutionException( "Failed to load plugin for: "
+ MojoBindingUtils.toString( mojoBinding ) + ". Reason: unknown" );
}
}
catch ( LifecycleExecutionException e )
@ -414,10 +409,11 @@ public class DefaultLifecycleExecutor
}
}
private boolean handleExecutionFailure( ReactorManager rm, MavenProject project, Exception e, MojoBinding mojoBinding,
long buildStartTime )
private boolean handleExecutionFailure( final ReactorManager rm, final MavenProject project, final Exception e,
final MojoBinding mojoBinding, final long buildStartTime )
{
rm.registerBuildFailure( project, e, MojoBindingUtils.toString( mojoBinding ), System.currentTimeMillis() - buildStartTime );
rm.registerBuildFailure( project, e, MojoBindingUtils.toString( mojoBinding ), System.currentTimeMillis()
- buildStartTime );
if ( ReactorManager.FAIL_FAST.equals( rm.getFailureBehavior() ) )
{
@ -431,7 +427,8 @@ public class DefaultLifecycleExecutor
return false;
}
private List segmentTaskListByAggregationNeeds( List tasks, MavenSession session, MavenProject rootProject )
private List segmentTaskListByAggregationNeeds( final List tasks, final MavenSession session,
final MavenProject rootProject )
throws LifecycleExecutionException, BuildFailureException
{
List segments = new ArrayList();
@ -448,7 +445,7 @@ public class DefaultLifecycleExecutor
// simply add it to the current task partition.
if ( LifecycleUtils.isValidPhaseName( task ) )
{
if ( currentSegment != null && currentSegment.aggregate() )
if ( ( currentSegment != null ) && currentSegment.aggregate() )
{
segments.add( currentSegment );
currentSegment = null;
@ -471,33 +468,37 @@ public class DefaultLifecycleExecutor
}
catch ( PluginLoaderException e )
{
// TODO: shouldn't hit this, investigate using the same resolution logic as
// TODO: shouldn't hit this, investigate using the same resolution logic as
// others for plugins in the reactor
getLogger().info(
"Cannot find mojo descriptor for: \'" + task + "\' - Treating as non-aggregator." );
"Cannot find mojo descriptor for: \'" + task
+ "\' - Treating as non-aggregator." );
getLogger().debug( "", e );
}
catch ( LifecycleSpecificationException e )
{
String message = "Invalid task '" + task + "': you must specify a valid lifecycle phase, or"
+ " a goal in the format plugin:goal or pluginGroupId:pluginArtifactId:pluginVersion:goal";
String message =
"Invalid task '"
+ task
+ "': you must specify a valid lifecycle phase, or"
+ " a goal in the format plugin:goal or pluginGroupId:pluginArtifactId:pluginVersion:goal";
throw new BuildFailureException( message, e );
}
catch ( LifecycleLoaderException e )
{
String message = "Cannot find plugin to match task '" + task + "'.";
throw new BuildFailureException( message, e );
}
// if the mojo descriptor was found, determine aggregator status according to:
// 1. whether the mojo declares itself an aggregator
// 2. whether the mojo DOES NOT require a project to function (implicitly avoid reactor)
if ( mojo != null && ( mojo.isAggregator() || !mojo.isProjectRequired() ) )
if ( ( mojo != null ) && ( mojo.isAggregator() || !mojo.isProjectRequired() ) )
{
if ( currentSegment != null && !currentSegment.aggregate() )
if ( ( currentSegment != null ) && !currentSegment.aggregate() )
{
segments.add( currentSegment );
currentSegment = null;
@ -512,7 +513,7 @@ public class DefaultLifecycleExecutor
}
else
{
if ( currentSegment != null && currentSegment.aggregate() )
if ( ( currentSegment != null ) && currentSegment.aggregate() )
{
segments.add( currentSegment );
currentSegment = null;
@ -545,18 +546,18 @@ public class DefaultLifecycleExecutor
/**
* @todo Not particularly happy about this. Would like WagonManager and ArtifactTypeHandlerManager to be able to
* lookup directly, or have them passed in
* lookup directly, or have them passed in
*
* @todo Move this sort of thing to the tail end of the project-building process
*/
private Map findArtifactTypeHandlers( MavenSession session )
private Map findArtifactTypeHandlers( final MavenSession session )
throws LifecycleExecutionException, PluginNotFoundException
{
Map map = new HashMap();
for ( Iterator projectIterator = session.getSortedProjects().iterator(); projectIterator.hasNext(); )
{
MavenProject project = (MavenProject) projectIterator.next();
for ( Iterator i = project.getBuildPlugins().iterator(); i.hasNext(); )
{
Plugin plugin = (Plugin) i.next();
@ -565,7 +566,8 @@ public class DefaultLifecycleExecutor
{
verifyPlugin( plugin, project, session );
// TODO: if moved to the plugin manager we already have the descriptor from above and so do can lookup the container directly
// TODO: if moved to the plugin manager we already have the descriptor from above and so do can
// lookup the container directly
try
{
Map components = pluginManager.getPluginComponents( plugin, ArtifactHandler.ROLE );
@ -577,8 +579,8 @@ public class DefaultLifecycleExecutor
}
catch ( PluginManagerException e )
{
throw new LifecycleExecutionException( "Error looking up available components from plugin '" +
plugin.getKey() + "': " + e.getMessage(), e );
throw new LifecycleExecutionException( "Error looking up available components from plugin '"
+ plugin.getKey() + "': " + e.getMessage(), e );
}
// shudder...
@ -596,11 +598,11 @@ public class DefaultLifecycleExecutor
return map;
}
private PluginDescriptor verifyPlugin( Plugin plugin, MavenProject project, MavenSession session )
private PluginDescriptor verifyPlugin( final Plugin plugin, final MavenProject project, final MavenSession session )
throws LifecycleExecutionException, PluginNotFoundException
{
getLogger().debug( "Verifying plugin: " + plugin.getKey() );
PluginDescriptor pluginDescriptor;
try
{
@ -608,8 +610,8 @@ public class DefaultLifecycleExecutor
}
catch ( PluginManagerException e )
{
throw new LifecycleExecutionException(
"Internal error in the plugin manager getting plugin '" + plugin.getKey() + "': " + e.getMessage(), e );
throw new LifecycleExecutionException( "Internal error in the plugin manager getting plugin '"
+ plugin.getKey() + "': " + e.getMessage(), e );
}
catch ( PluginVersionResolutionException e )
{
@ -638,14 +640,15 @@ public class DefaultLifecycleExecutor
return pluginDescriptor;
}
private MojoDescriptor getMojoDescriptorForDirectInvocation( String task, MavenSession session, MavenProject project )
private MojoDescriptor getMojoDescriptorForDirectInvocation( final String task, final MavenSession session,
final MavenProject project )
throws LifecycleSpecificationException, PluginLoaderException, LifecycleLoaderException
{
MojoBinding binding = mojoBindingFactory.parseMojoBinding( task, project, true );
PluginDescriptor descriptor = pluginLoader.loadPlugin( binding, project );
MojoDescriptor mojoDescriptor = descriptor.getMojo( binding.getGoal() );
return mojoDescriptor;
}
@ -658,14 +661,14 @@ public class DefaultLifecycleExecutor
{
private boolean aggregate;
private List tasks = new ArrayList();
private final List tasks = new ArrayList();
TaskSegment()
{
}
TaskSegment( boolean aggregate )
TaskSegment( final boolean aggregate )
{
this.aggregate = aggregate;
}
@ -703,7 +706,7 @@ public class DefaultLifecycleExecutor
return aggregate;
}
void add( String task )
void add( final String task )
{
tasks.add( task );
}

View File

@ -5,11 +5,8 @@ import org.apache.maven.lifecycle.LifecycleLoaderException;
import org.apache.maven.lifecycle.LifecycleSpecificationException;
import org.apache.maven.lifecycle.LifecycleUtils;
import org.apache.maven.lifecycle.mapping.LifecycleMapping;
import org.apache.maven.lifecycle.model.LifecycleBinding;
import org.apache.maven.lifecycle.model.LifecycleBindings;
import org.apache.maven.lifecycle.model.MojoBinding;
import org.apache.maven.lifecycle.plan.DirectInvocationModifier;
import org.apache.maven.lifecycle.plan.LifecyclePlannerException;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.PluginExecution;
import org.apache.maven.model.ReportPlugin;
@ -30,23 +27,20 @@ import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
/**
* Responsible for the gross construction of LifecycleBindings, or mappings of MojoBinding instances
* to different parts of the three lifecycles: clean, build, and site. Also, handles transcribing
* these LifecycleBindings instances into lists of MojoBinding's, which can be consumed by the
* LifecycleExecutor.
* Responsible for the gross construction of LifecycleBindings, or mappings of MojoBinding instances to different parts
* of the three lifecycles: clean, build, and site. Also, handles transcribing these LifecycleBindings instances into
* lists of MojoBinding's, which can be consumed by the LifecycleExecutor.
*
* @author jdcasey
*
*
*/
public class DefaultLifecycleBindingManager
implements LifecycleBindingManager, LogEnabled
public class DefaultLifecycleBindingManager implements LifecycleBindingManager, LogEnabled
{
private ActiveMap bindingsByPackaging;
@ -56,7 +50,7 @@ public class DefaultLifecycleBindingManager
private PluginLoader pluginLoader;
private MojoBindingFactory mojoBindingFactory;
private LegacyLifecycleMappingParser legacyLifecycleMappingParser;
private Logger logger;
@ -68,11 +62,10 @@ public class DefaultLifecycleBindingManager
private List defaultReports;
/**
* Retrieve the LifecycleBindings given by the lifecycle mapping component/file for the project's
* packaging. Any applicable mojo configuration will be injected into the LifecycleBindings from
* the POM.
* Retrieve the LifecycleBindings given by the lifecycle mapping component/file for the project's packaging. Any
* applicable mojo configuration will be injected into the LifecycleBindings from the POM.
*/
public LifecycleBindings getBindingsForPackaging( MavenProject project )
public LifecycleBindings getBindingsForPackaging( final MavenProject project )
throws LifecycleLoaderException, LifecycleSpecificationException
{
String packaging = project.getPackaging();
@ -114,12 +107,11 @@ public class DefaultLifecycleBindingManager
/**
* Search all plugins configured in the POM that have extensions == true, looking for either a
* {@link LifecycleBindingLoader} instance, or a {@link LifecycleMapping} instance that matches
* the project's packaging. For the first match found, construct the corresponding LifecycleBindings
* instance and return it after POM configurations have been injected into any appropriate
* MojoBinding instances contained within.
* {@link LifecycleBindingLoader} instance, or a {@link LifecycleMapping} instance that matches the project's
* packaging. For the first match found, construct the corresponding LifecycleBindings instance and return it after
* POM configurations have been injected into any appropriate MojoBinding instances contained within.
*/
private LifecycleBindings searchPluginsWithExtensions( MavenProject project )
private LifecycleBindings searchPluginsWithExtensions( final MavenProject project )
throws LifecycleLoaderException, LifecycleSpecificationException
{
List plugins = project.getBuildPlugins();
@ -136,18 +128,20 @@ public class DefaultLifecycleBindingManager
try
{
loader = (LifecycleBindingLoader) pluginLoader.loadPluginComponent( LifecycleBindingLoader.ROLE, packaging,
plugin, project );
loader =
(LifecycleBindingLoader) pluginLoader.loadPluginComponent( LifecycleBindingLoader.ROLE,
packaging, plugin, project );
}
catch ( ComponentLookupException e )
{
logger.debug( LifecycleBindingLoader.ROLE + " for packaging: " + packaging
+ " could not be retrieved from plugin: " + plugin.getKey() + ".\nReason: " + e.getMessage(), e );
+ " could not be retrieved from plugin: " + plugin.getKey() + ".\nReason: "
+ e.getMessage(), e );
}
catch ( PluginLoaderException e )
{
throw new LifecycleLoaderException( "Failed to load plugin: " + plugin.getKey() + ". Reason: "
+ e.getMessage(), e );
+ e.getMessage(), e );
}
if ( loader != null )
@ -161,18 +155,20 @@ public class DefaultLifecycleBindingManager
LifecycleMapping mapping = null;
try
{
mapping = (LifecycleMapping) pluginLoader.loadPluginComponent( LifecycleMapping.ROLE, packaging, plugin,
project );
mapping =
(LifecycleMapping) pluginLoader.loadPluginComponent( LifecycleMapping.ROLE, packaging,
plugin, project );
}
catch ( ComponentLookupException e )
{
logger.debug( LifecycleMapping.ROLE + " for packaging: " + packaging
+ " could not be retrieved from plugin: " + plugin.getKey() + ".\nReason: " + e.getMessage(), e );
+ " could not be retrieved from plugin: " + plugin.getKey() + ".\nReason: "
+ e.getMessage(), e );
}
catch ( PluginLoaderException e )
{
throw new LifecycleLoaderException( "Failed to load plugin: " + plugin.getKey() + ". Reason: "
+ e.getMessage(), e );
+ e.getMessage(), e );
}
if ( mapping != null )
@ -197,11 +193,10 @@ public class DefaultLifecycleBindingManager
}
/**
* Construct the LifecycleBindings for the default lifecycle mappings, including injection of
* configuration from the project into each MojoBinding, where appropriate.
* Construct the LifecycleBindings for the default lifecycle mappings, including injection of configuration from the
* project into each MojoBinding, where appropriate.
*/
public LifecycleBindings getDefaultBindings( MavenProject project )
throws LifecycleSpecificationException
public LifecycleBindings getDefaultBindings( final MavenProject project ) throws LifecycleSpecificationException
{
LifecycleBindings bindings = legacyLifecycleMappingParser.parseDefaultMappings( legacyLifecycles );
@ -210,16 +205,15 @@ public class DefaultLifecycleBindingManager
return bindings;
}
public void enableLogging( Logger logger )
public void enableLogging( final Logger logger )
{
this.logger = logger;
}
/**
* Construct the LifecycleBindings that constitute the extra mojos bound to the lifecycle within
* the POM itself.
* Construct the LifecycleBindings that constitute the extra mojos bound to the lifecycle within the POM itself.
*/
public LifecycleBindings getProjectCustomBindings( MavenProject project )
public LifecycleBindings getProjectCustomBindings( final MavenProject project )
throws LifecycleLoaderException, LifecycleSpecificationException
{
String projectId = project.getId();
@ -245,15 +239,16 @@ public class DefaultLifecycleBindingManager
PluginExecution execution = (PluginExecution) execIt.next();
List goals = execution.getGoals();
if ( goals != null && !goals.isEmpty() )
if ( ( goals != null ) && !goals.isEmpty() )
{
for ( Iterator goalIterator = goals.iterator(); goalIterator.hasNext(); )
{
String goal = (String) goalIterator.next();
if ( goal == null )
{
logger.warn( "Execution: " + execution.getId() + " in plugin: " + plugin.getKey() + " in the POM has a null goal." );
logger.warn( "Execution: " + execution.getId() + " in plugin: " + plugin.getKey()
+ " in the POM has a null goal." );
continue;
}
@ -278,14 +273,15 @@ public class DefaultLifecycleBindingManager
}
catch ( PluginLoaderException e )
{
throw new LifecycleLoaderException( "Failed to load plugin: " + plugin + ". Reason: "
+ e.getMessage(), e );
throw new LifecycleLoaderException( "Failed to load plugin: " + plugin
+ ". Reason: " + e.getMessage(), e );
}
}
if ( pluginDescriptor.getMojos() == null )
{
logger.error( "Somehow, the PluginDescriptor for plugin: " + plugin.getKey() + " contains no mojos. This is highly irregular. Ignoring..." );
logger.error( "Somehow, the PluginDescriptor for plugin: " + plugin.getKey()
+ " contains no mojos. This is highly irregular. Ignoring..." );
continue;
}
@ -294,8 +290,9 @@ public class DefaultLifecycleBindingManager
if ( phase == null )
{
throw new LifecycleSpecificationException( "No phase specified for goal: " + goal
+ " in plugin: " + plugin.getKey() + " from POM: " + projectId );
throw new LifecycleSpecificationException( "No phase specified for goal: "
+ goal + " in plugin: " + plugin.getKey() + " from POM: "
+ projectId );
}
}
@ -313,12 +310,11 @@ public class DefaultLifecycleBindingManager
}
/**
* Construct the LifecycleBindings that constitute the mojos mapped to the lifecycles by an overlay
* specified in a plugin. Inject mojo configuration from the POM into all appropriate MojoBinding
* instances.
* Construct the LifecycleBindings that constitute the mojos mapped to the lifecycles by an overlay specified in a
* plugin. Inject mojo configuration from the POM into all appropriate MojoBinding instances.
*/
public LifecycleBindings getPluginLifecycleOverlay( PluginDescriptor pluginDescriptor, String lifecycleId,
MavenProject project )
public LifecycleBindings getPluginLifecycleOverlay( final PluginDescriptor pluginDescriptor,
final String lifecycleId, final MavenProject project )
throws LifecycleLoaderException, LifecycleSpecificationException
{
Lifecycle lifecycleOverlay = null;
@ -362,21 +358,21 @@ public class DefaultLifecycleBindingManager
// An example of this is the corbertura plugin that needs to call the surefire
// plugin in forking mode.
//
//<phase>
// <id>test</id>
// <executions>
// <execution>
// <goals>
// <goal>org.apache.maven.plugins:maven-surefire-plugin:test</goal>
// </goals>
// <configuration>
// <classesDirectory>${project.build.directory}/generated-classes/cobertura</classesDirectory>
// <ignoreFailures>true</ignoreFailures>
// <forkMode>once</forkMode>
// </configuration>
// </execution>
// </executions>
//</phase>
// <phase>
// <id>test</id>
// <executions>
// <execution>
// <goals>
// <goal>org.apache.maven.plugins:maven-surefire-plugin:test</goal>
// </goals>
// <configuration>
// <classesDirectory>${project.build.directory}/generated-classes/cobertura</classesDirectory>
// <ignoreFailures>true</ignoreFailures>
// <forkMode>once</forkMode>
// </configuration>
// </execution>
// </executions>
// </phase>
// ----------------------------------------------------------------------
//
@ -399,7 +395,8 @@ public class DefaultLifecycleBindingManager
Xpp3Dom configuration = (Xpp3Dom) exec.getConfiguration();
if ( phase.getConfiguration() != null )
{
configuration = Xpp3Dom.mergeXpp3Dom( new Xpp3Dom( (Xpp3Dom) phase.getConfiguration() ), configuration );
configuration =
Xpp3Dom.mergeXpp3Dom( new Xpp3Dom( (Xpp3Dom) phase.getConfiguration() ), configuration );
}
binding.setConfiguration( configuration );
@ -414,15 +411,16 @@ public class DefaultLifecycleBindingManager
{
// Merge in general configuration for a phase.
// TODO: this is all kind of backwards from the POMM. Let's align it all under 2.1.
// We should create a new lifecycle executor for modelVersion >5.0.0
// We should create a new lifecycle executor for modelVersion >5.0.0
// [jdcasey; 08-March-2007] Not sure what the above to-do references...how _should_
// this work??
for ( Iterator j = phaseBindings.iterator(); j.hasNext(); )
{
MojoBinding binding = (MojoBinding) j.next();
Xpp3Dom configuration = Xpp3Dom.mergeXpp3Dom( new Xpp3Dom( (Xpp3Dom) phase.getConfiguration() ),
(Xpp3Dom) binding.getConfiguration() );
Xpp3Dom configuration =
Xpp3Dom.mergeXpp3Dom( new Xpp3Dom( (Xpp3Dom) phase.getConfiguration() ),
(Xpp3Dom) binding.getConfiguration() );
binding.setConfiguration( configuration );
}
@ -434,18 +432,17 @@ public class DefaultLifecycleBindingManager
}
/**
* Retrieve the list of MojoBinding instances that correspond to the reports configured for the
* specified project. Inject all appropriate configuration from the POM for each MojoBinding, using
* the following precedence rules:
* Retrieve the list of MojoBinding instances that correspond to the reports configured for the specified project.
* Inject all appropriate configuration from the POM for each MojoBinding, using the following precedence rules:
* <br/>
* <ol>
* <li>report-set-level configuration</li>
* <li>reporting-level configuration</li>
* <li>execution-level configuration</li>
* <li>plugin-level configuration</li>
* <li>report-set-level configuration</li>
* <li>reporting-level configuration</li>
* <li>execution-level configuration</li>
* <li>plugin-level configuration</li>
* </ol>
*/
public List getReportBindings( MavenProject project )
public List getReportBindings( final MavenProject project )
throws LifecycleLoaderException, LifecycleSpecificationException
{
if ( project.getModel().getReports() != null )
@ -464,7 +461,7 @@ public class DefaultLifecycleBindingManager
List reportSets = reportPlugin.getReportSets();
if ( reportSets == null || reportSets.isEmpty() )
if ( ( reportSets == null ) || reportSets.isEmpty() )
{
reports.addAll( getReportsForPlugin( reportPlugin, null, project ) );
}
@ -485,11 +482,11 @@ public class DefaultLifecycleBindingManager
/**
* Retrieve the ReportPlugin instances referenced in the specified POM.
*/
private List getReportPluginsForProject( MavenProject project )
private List getReportPluginsForProject( final MavenProject project )
{
List reportPlugins = project.getReportPlugins();
if ( project.getReporting() == null || !project.getReporting().isExcludeDefaults() )
if ( ( project.getReporting() == null ) || !project.getReporting().isExcludeDefaults() )
{
if ( reportPlugins == null )
{
@ -518,7 +515,8 @@ public class DefaultLifecycleBindingManager
for ( Iterator j = reportPlugins.iterator(); j.hasNext() && !found; )
{
ReportPlugin reportPlugin = (ReportPlugin) j.next();
if ( reportPlugin.getGroupId().equals( groupId ) && reportPlugin.getArtifactId().equals( artifactId ) )
if ( reportPlugin.getGroupId().equals( groupId )
&& reportPlugin.getArtifactId().equals( artifactId ) )
{
found = true;
}
@ -541,8 +539,8 @@ public class DefaultLifecycleBindingManager
/**
* Retrieve any reports from the specified ReportPlugin which are referenced in the specified POM.
*/
private List getReportsForPlugin( ReportPlugin reportPlugin, ReportSet reportSet, MavenProject project )
throws LifecycleLoaderException
private List getReportsForPlugin( final ReportPlugin reportPlugin, final ReportSet reportSet,
final MavenProject project ) throws LifecycleLoaderException
{
PluginDescriptor pluginDescriptor;
try
@ -552,7 +550,7 @@ public class DefaultLifecycleBindingManager
catch ( PluginLoaderException e )
{
throw new LifecycleLoaderException( "Failed to load report plugin: " + reportPlugin.getKey() + ". Reason: "
+ e.getMessage(), e );
+ e.getMessage(), e );
}
String pluginKey = BindingUtils.createPluginKey( reportPlugin.getGroupId(), reportPlugin.getArtifactId() );
@ -565,7 +563,7 @@ public class DefaultLifecycleBindingManager
// TODO: check ID is correct for reports
// if the POM configured no reports, give all from plugin
if ( reportSet == null || reportSet.getReports().contains( mojoDescriptor.getGoal() ) )
if ( ( reportSet == null ) || reportSet.getReports().contains( mojoDescriptor.getGoal() ) )
{
String id = null;
if ( reportSet != null )
@ -589,7 +587,7 @@ public class DefaultLifecycleBindingManager
plugin.setGroupId( pluginDescriptor.getGroupId() );
plugin.setArtifactId( pluginDescriptor.getArtifactId() );
}
BindingUtils.injectPluginManagementInfo( plugin, project );
Map execMap = plugin.getExecutionsAsMap();
@ -611,126 +609,4 @@ public class DefaultLifecycleBindingManager
return reports;
}
/**
* Determine whether the first list contains all of the same MojoBinding instances, in the same
* order, starting at index zero, as the second list. If so, it is either a perfect super-list
* or an equal list, and return true. Return false otherwise.
*/
private static boolean isSameOrSuperListOfMojoBindings( List superCandidate, List check )
{
if ( superCandidate == null || check == null )
{
return false;
}
if ( superCandidate.size() < check.size() )
{
return false;
}
List superKeys = new ArrayList( superCandidate.size() );
for ( Iterator it = superCandidate.iterator(); it.hasNext(); )
{
MojoBinding binding = (MojoBinding) it.next();
superKeys.add( LifecycleUtils.createMojoBindingKey( binding, true ) );
}
List checkKeys = new ArrayList( check.size() );
for ( Iterator it = check.iterator(); it.hasNext(); )
{
MojoBinding binding = (MojoBinding) it.next();
checkKeys.add( LifecycleUtils.createMojoBindingKey( binding, true ) );
}
return superKeys.subList( 0, checkKeys.size() ).equals( checkKeys );
}
/**
* Traverse the specified LifecycleBindings instance for all of the specified tasks. If the task
* is found to be a phase name, construct the list of all MojoBindings that lead up to that phase
* in that lifecycle, and add them to the master MojoBinding list. If the task is not a phase name,
* treat it as a direct mojo invocation, parse it into a MojoBinding (resolving the plugin prefix
* first if necessary), and add it to the master MojoBinding list. Finally, return the master list.
*/
public List assembleMojoBindingList( List tasks, LifecycleBindings bindings, MavenProject project )
throws LifecycleSpecificationException, LifecyclePlannerException, LifecycleLoaderException
{
return assembleMojoBindingList( tasks, bindings, Collections.EMPTY_MAP, project );
}
/**
* Traverse the specified LifecycleBindings instance for all of the specified tasks. If the task
* is found to be a phase name, construct the list of all MojoBindings that lead up to that phase
* in that lifecycle, and add them to the master MojoBinding list. If the task is not a phase name,
* treat it as a direct mojo invocation, parse it into a MojoBinding (resolving the plugin prefix
* first if necessary), and add it to the master MojoBinding list.
*
* Then, iterate through all MojoBindings in the master list, and for each one that maps to an
* entry in directInvocationModifiers, substitute the resultant MojoBinding list from that
* modifier in place of the original MojoBinding.
*
* Finally, return the modified master list.
*/
public List assembleMojoBindingList( List tasks, LifecycleBindings lifecycleBindings, Map directInvocationModifiers,
MavenProject project )
throws LifecycleSpecificationException, LifecyclePlannerException, LifecycleLoaderException
{
List planBindings = new ArrayList();
List lastMojoBindings = null;
for ( Iterator it = tasks.iterator(); it.hasNext(); )
{
String task = (String) it.next();
LifecycleBinding binding = LifecycleUtils.findLifecycleBindingForPhase( task, lifecycleBindings );
if ( binding != null )
{
List mojoBindings = LifecycleUtils.getMojoBindingListForLifecycle( task, binding );
// save these so we can reference the originals...
List originalMojoBindings = mojoBindings;
// if these mojo bindings are a superset of the last bindings, only add the difference.
if ( isSameOrSuperListOfMojoBindings( mojoBindings, lastMojoBindings ) )
{
List revised = new ArrayList( mojoBindings );
revised.removeAll( lastMojoBindings );
if ( revised.isEmpty() )
{
continue;
}
mojoBindings = revised;
}
planBindings.addAll( mojoBindings );
lastMojoBindings = originalMojoBindings;
}
else
{
MojoBinding mojoBinding = mojoBindingFactory.parseMojoBinding( task, project, true );
BindingUtils.injectProjectConfiguration( mojoBinding, project );
mojoBinding.setOrigin( "direct invocation" );
String key = LifecycleUtils.createMojoBindingKey( mojoBinding, true );
DirectInvocationModifier modifier = (DirectInvocationModifier) directInvocationModifiers.get( key );
if ( modifier != null )
{
planBindings.addAll( modifier.getModifiedBindings( project, this ) );
}
else
{
planBindings.add( mojoBinding );
}
}
}
return planBindings;
}
}

View File

@ -3,21 +3,18 @@ package org.apache.maven.lifecycle.binding;
import org.apache.maven.lifecycle.LifecycleLoaderException;
import org.apache.maven.lifecycle.LifecycleSpecificationException;
import org.apache.maven.lifecycle.model.LifecycleBindings;
import org.apache.maven.lifecycle.plan.LifecyclePlannerException;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.project.MavenProject;
import java.util.List;
import java.util.Map;
/**
* Responsible for the gross construction of LifecycleBindings, or mappings of MojoBinding instances
* to different parts of the three lifecycles: clean, build, and site. Also, handles transcribing
* these LifecycleBindings instances into lists of MojoBinding's, which can be consumed by the
* LifecycleExecutor.
* Responsible for the gross construction of LifecycleBindings, or mappings of MojoBinding instances to different parts
* of the three lifecycles: clean, build, and site. Also, handles transcribing these LifecycleBindings instances into
* lists of MojoBinding's, which can be consumed by the LifecycleExecutor.
*
* @author jdcasey
*
*
*/
public interface LifecycleBindingManager
{
@ -25,74 +22,43 @@ public interface LifecycleBindingManager
String ROLE = LifecycleBindingManager.class.getName();
/**
* Construct the LifecycleBindings for the default lifecycle mappings, including injection of
* configuration from the project into each MojoBinding, where appropriate.
* Construct the LifecycleBindings for the default lifecycle mappings, including injection of configuration from the
* project into each MojoBinding, where appropriate.
*/
LifecycleBindings getDefaultBindings( MavenProject project )
throws LifecycleSpecificationException;
LifecycleBindings getDefaultBindings( MavenProject project ) throws LifecycleSpecificationException;
/**
* Retrieve the LifecycleBindings given by the lifecycle mapping component/file for the project's
* packaging. Any applicable mojo configuration will be injected into the LifecycleBindings from
* the POM.
* Retrieve the LifecycleBindings given by the lifecycle mapping component/file for the project's packaging. Any
* applicable mojo configuration will be injected into the LifecycleBindings from the POM.
*/
LifecycleBindings getBindingsForPackaging( MavenProject project )
throws LifecycleLoaderException, LifecycleSpecificationException;
/**
* Construct the LifecycleBindings that constitute the extra mojos bound to the lifecycle within
* the POM itself.
* Construct the LifecycleBindings that constitute the extra mojos bound to the lifecycle within the POM itself.
*/
LifecycleBindings getProjectCustomBindings( MavenProject project )
throws LifecycleLoaderException, LifecycleSpecificationException;
/**
* Construct the LifecycleBindings that constitute the mojos mapped to the lifecycles by an overlay
* specified in a plugin. Inject mojo configuration from the POM into all appropriate MojoBinding
* instances.
* Construct the LifecycleBindings that constitute the mojos mapped to the lifecycles by an overlay specified in a
* plugin. Inject mojo configuration from the POM into all appropriate MojoBinding instances.
*/
LifecycleBindings getPluginLifecycleOverlay( PluginDescriptor pluginDescriptor, String lifecycleId, MavenProject project )
LifecycleBindings getPluginLifecycleOverlay( PluginDescriptor pluginDescriptor, String lifecycleId,
MavenProject project )
throws LifecycleLoaderException, LifecycleSpecificationException;
/**
* Retrieve the list of MojoBinding instances that correspond to the reports configured for the
* specified project. Inject all appropriate configuration from the POM for each MojoBinding, using
* the following precedence rules:
* Retrieve the list of MojoBinding instances that correspond to the reports configured for the specified project.
* Inject all appropriate configuration from the POM for each MojoBinding, using the following precedence rules:
* <br/>
* <ol>
* <li>report-set-level configuration</li>
* <li>reporting-level configuration</li>
* <li>execution-level configuration</li>
* <li>plugin-level configuration</li>
* <li>report-set-level configuration</li>
* <li>reporting-level configuration</li>
* <li>execution-level configuration</li>
* <li>plugin-level configuration</li>
* </ol>
*/
List getReportBindings( MavenProject project )
throws LifecycleLoaderException, LifecycleSpecificationException;
/**
* Traverse the specified LifecycleBindings instance for all of the specified tasks. If the task
* is found to be a phase name, construct the list of all MojoBindings that lead up to that phase
* in that lifecycle, and add them to the master MojoBinding list. If the task is not a phase name,
* treat it as a direct mojo invocation, parse it into a MojoBinding (resolving the plugin prefix
* first if necessary), and add it to the master MojoBinding list.
*
* Then, iterate through all MojoBindings in the master list, and for each one that maps to an
* entry in directInvocationModifiers, substitute the resultant MojoBinding list from that
* modifier in place of the original MojoBinding.
*
* Finally, return the modified master list.
*/
List assembleMojoBindingList( List tasks, LifecycleBindings bindings, Map directInvocationModifiers, MavenProject project )
throws LifecycleSpecificationException, LifecyclePlannerException, LifecycleLoaderException;
/**
* Traverse the specified LifecycleBindings instance for all of the specified tasks. If the task
* is found to be a phase name, construct the list of all MojoBindings that lead up to that phase
* in that lifecycle, and add them to the master MojoBinding list. If the task is not a phase name,
* treat it as a direct mojo invocation, parse it into a MojoBinding (resolving the plugin prefix
* first if necessary), and add it to the master MojoBinding list. Finally, return the master list.
*/
List assembleMojoBindingList( List tasks, LifecycleBindings lifecycleBindings, MavenProject project )
throws LifecycleSpecificationException, LifecyclePlannerException, LifecycleLoaderException;
List getReportBindings( MavenProject project ) throws LifecycleLoaderException, LifecycleSpecificationException;
}

View File

@ -0,0 +1,282 @@
package org.apache.maven.lifecycle.plan;
import org.apache.maven.lifecycle.LifecycleLoaderException;
import org.apache.maven.lifecycle.LifecycleSpecificationException;
import org.apache.maven.lifecycle.LifecycleUtils;
import org.apache.maven.lifecycle.MojoBindingUtils;
import org.apache.maven.lifecycle.NoSuchPhaseException;
import org.apache.maven.lifecycle.model.LifecycleBinding;
import org.apache.maven.lifecycle.model.LifecycleBindings;
import org.apache.maven.lifecycle.model.MojoBinding;
import org.apache.maven.lifecycle.statemgmt.StateManagementUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;
public class BuildPlan
{
private LifecycleBindings bindings;
private final List tasks;
private final Map forks;
private final List lateBoundMojos;
private List renderedLifecycleMojos = new ArrayList();
private final Map directInvocationBindings;
public BuildPlan( final LifecycleBindings packaging, final LifecycleBindings projectBindings,
final LifecycleBindings defaults, final List tasks )
throws LifecycleSpecificationException, LifecycleLoaderException
{
this( LifecycleUtils.mergeBindings( packaging, projectBindings, defaults, true, false ), tasks );
}
public BuildPlan( final LifecycleBindings bindings, final List tasks )
throws LifecycleSpecificationException, LifecycleLoaderException
{
this.bindings = bindings;
this.tasks = tasks;
forks = new HashMap();
lateBoundMojos = new ArrayList();
directInvocationBindings = new HashMap();
}
private BuildPlan( final LifecycleBindings bindings, final Map forks, final List lateBoundMojos,
final Map directInvocationBindings, final List tasks )
{
this.bindings = LifecycleUtils.cloneBindings( bindings );
this.forks = new HashMap( forks );
this.lateBoundMojos = new ArrayList( lateBoundMojos );
this.tasks = tasks;
this.directInvocationBindings = new HashMap( directInvocationBindings );
}
public void addLifecycleOverlay( final LifecycleBindings overlay )
{
bindings = LifecycleUtils.mergeBindings( overlay, bindings, null, true, true );
}
public void addTask( final String task, final MojoBinding binding )
throws LifecycleSpecificationException, LifecycleLoaderException
{
tasks.add( task );
if ( !LifecycleUtils.isValidPhaseName( task ) )
{
addDirectInvocationBinding( task, binding );
}
}
public LifecycleBindings getLifecycleBindings()
{
return bindings;
}
public List getTasks()
{
return tasks;
}
public void addDirectInvocationBinding( final String key, final MojoBinding binding )
{
directInvocationBindings.put( MojoBindingUtils.createMojoBindingKey( binding, false ), binding );
directInvocationBindings.put( key, binding );
}
public List getLateBoundMojos()
{
return lateBoundMojos;
}
public Map getDirectInvocationBindings()
{
return directInvocationBindings;
}
public Map getForks()
{
return forks;
}
public void addForkedExecution( final MojoBinding mojoBinding, final BuildPlan plan )
{
String key = MojoBindingUtils.createMojoBindingKey( mojoBinding, false );
forks.put( key, plan );
}
public void addForkedExecution( final MojoBinding mojoBinding, final List forkedInvocations )
{
String key = MojoBindingUtils.createMojoBindingKey( mojoBinding, false );
forks.put( key, forkedInvocations );
}
public void addLateBoundMojo( final MojoBinding mojoBinding )
{
lateBoundMojos.add( MojoBindingUtils.createMojoBindingKey( mojoBinding, false ) );
}
public BuildPlan copy( final List newTasks )
{
return new BuildPlan( bindings, forks, lateBoundMojos, directInvocationBindings, newTasks );
}
public void resetExecutionProgress()
{
renderedLifecycleMojos = new ArrayList();
}
public List renderExecutionPlan( final Stack executionStack )
throws NoSuchPhaseException
{
List plan = new ArrayList();
for ( Iterator it = tasks.iterator(); it.hasNext(); )
{
String task = (String) it.next();
if ( LifecycleUtils.isValidPhaseName( task ) )
{
// find the lifecyle that this task belongs in...
LifecycleBinding binding = LifecycleUtils.findLifecycleBindingForPhase( task, bindings );
// get the list of mojo bindings before or at the specified phase in the lifecycle
List bindingsToAdd = LifecycleUtils.getMojoBindingListForLifecycle( task, binding );
// backup copy for rendered tracking...
List newRendered = new ArrayList( bindingsToAdd );
// if we've already executed part of the lifecycle, just continue with the new bindings.
if ( ( renderedLifecycleMojos != null ) && ( renderedLifecycleMojos.size() < bindingsToAdd.size() ) )
{
bindingsToAdd = bindingsToAdd.subList( renderedLifecycleMojos.size(), bindingsToAdd.size() );
}
// save the current binding list for tracking progress through the lifecycle.
renderedLifecycleMojos = newRendered;
for ( Iterator itMojos = bindingsToAdd.iterator(); itMojos.hasNext(); )
{
MojoBinding mojoBinding = (MojoBinding) itMojos.next();
String key = MojoBindingUtils.createMojoBindingKey( mojoBinding, false );
if ( !executionStack.contains( key ) )
{
addResolverIfLateBound( mojoBinding, plan );
plan.addAll( findForkedBindings( mojoBinding, executionStack ) );
}
}
}
else
{
MojoBinding mojoBinding = (MojoBinding) directInvocationBindings.get( task );
String key = MojoBindingUtils.createMojoBindingKey( mojoBinding, false );
if ( !executionStack.contains( key ) )
{
addResolverIfLateBound( mojoBinding, plan );
plan.addAll( findForkedBindings( mojoBinding, executionStack ) );
}
}
}
return plan;
}
private void addResolverIfLateBound( final MojoBinding mojoBinding, final List plan )
{
String key = MojoBindingUtils.createMojoBindingKey( mojoBinding, false );
if ( lateBoundMojos.contains( key ) )
{
MojoBinding resolveBinding = StateManagementUtils.createResolveLateBoundMojoBinding( mojoBinding );
plan.add( resolveBinding );
}
}
private List findForkedBindings( final MojoBinding mojoBinding, final Stack executionStack )
throws NoSuchPhaseException
{
List bindings = new ArrayList();
String key = MojoBindingUtils.createMojoBindingKey( mojoBinding, false );
// let's see if we have any forks...
Object fork = forks.get( key );
executionStack.push( key );
try
{
if ( fork != null )
{
List forkedBindings = new ArrayList();
// if the fork is a build plan, recurse into it and retrieve the execution plan.
if ( fork instanceof BuildPlan )
{
forkedBindings = ( (BuildPlan) fork ).renderExecutionPlan( executionStack );
}
// leave room for new kinds of forks, and do some extra validation...
// if this is a list, it's a list of direct mojo invocations...we have to see if they have their own
// forks.
else if ( fork instanceof List )
{
List directInvocations = (List) fork;
for ( Iterator it = directInvocations.iterator(); it.hasNext(); )
{
MojoBinding invocation = (MojoBinding) it.next();
String invocationKey = MojoBindingUtils.createMojoBindingKey( invocation, false );
if ( executionStack.contains( invocationKey ) )
{
continue;
}
executionStack.push( MojoBindingUtils.createMojoBindingKey( mojoBinding, false ) );
try
{
addResolverIfLateBound( invocation, forkedBindings );
forkedBindings.addAll( findForkedBindings( invocation, executionStack ) );
}
finally
{
executionStack.pop();
}
}
}
if ( !forkedBindings.isEmpty() )
{
bindings.add( StateManagementUtils.createStartForkedExecutionMojoBinding() );
bindings.addAll( forkedBindings );
bindings.add( StateManagementUtils.createClearForkedExecutionMojoBinding() );
}
bindings.add( mojoBinding );
if ( !forkedBindings.isEmpty() )
{
bindings.add( StateManagementUtils.createEndForkedExecutionMojoBinding() );
}
}
else
{
bindings.add( mojoBinding );
}
}
finally
{
executionStack.pop();
}
return bindings;
}
}

View File

@ -1,19 +0,0 @@
package org.apache.maven.lifecycle.plan;
import org.apache.maven.lifecycle.LifecycleLoaderException;
import org.apache.maven.lifecycle.LifecycleSpecificationException;
import org.apache.maven.lifecycle.binding.LifecycleBindingManager;
import org.apache.maven.project.MavenProject;
import java.util.List;
public interface BuildPlanIfc
extends ModifiablePlanElement
{
List getPlanMojoBindings(MavenProject project, LifecycleBindingManager bindingManager)
throws LifecycleSpecificationException, LifecyclePlannerException, LifecycleLoaderException;
List getTasks();
}

View File

@ -1,20 +0,0 @@
package org.apache.maven.lifecycle.plan;
import org.apache.maven.lifecycle.model.LifecycleBindings;
/**
* Modifies an existing set of lifecycle mojo bindings, in order to inject extra behavior, such as
* forked executions, reporting, etc.
*/
public interface BuildPlanModifier extends ModifiablePlanElement
{
/**
* Inject any modifications into the given LifecycleBindings provided by the build plan. In some
* cases, it may be necessary to regenerate the LifecycleBindings instance, so the altered instance
* is returned separately.
*/
LifecycleBindings modifyBindings( LifecycleBindings bindings )
throws LifecyclePlannerException;
}

View File

@ -1,21 +1,17 @@
package org.apache.maven.lifecycle.plan;
import org.apache.maven.lifecycle.LifecycleLoaderException;
import org.apache.maven.lifecycle.LifecycleSpecificationException;
import org.apache.maven.lifecycle.LifecycleUtils;
import org.apache.maven.lifecycle.MojoBindingUtils;
import org.apache.maven.lifecycle.binding.LifecycleBindingManager;
import org.apache.maven.lifecycle.model.LifecycleBindings;
import org.apache.maven.lifecycle.model.MojoBinding;
import org.apache.maven.lifecycle.statemgmt.StateManagementUtils;
import org.apache.maven.project.MavenProject;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
/**
* Collection of static utility methods used to work with LifecycleBindings and other collections
* of MojoBinding instances that make up a build plan.
* Collection of static utility methods used to work with LifecycleBindings and other collections of MojoBinding
* instances that make up a build plan.
*/
public final class BuildPlanUtils
{
@ -25,55 +21,23 @@ public final class BuildPlanUtils
}
/**
* Inject a set of {@link BuildPlanModifier} instances into an existing LifecycleBindings instance.
* This is a generalization of a piece of code present in almost all scenarios where a build
* plan contains modifiers and is asked to produce an effective list of MojoBinding instances
* that make up the build process. Simply iterate through the modifiers, and apply each one,
* replacing the previous LifecycleBindings instance with the result of the current modifier.
* Render an entire build plan to a String. If extendedInfo == true, include each MojoBinding's configuration in the
* output.
*/
public static LifecycleBindings modifyPlanBindings( LifecycleBindings bindings, List planModifiers )
throws LifecyclePlannerException
public static String listBuildPlan( final BuildPlan plan, final boolean extendedInfo )
throws LifecycleSpecificationException, LifecyclePlannerException
{
LifecycleBindings result;
List mojos = plan.renderExecutionPlan( new Stack() );
plan.resetExecutionProgress();
// if the bindings are completely empty, passing in null avoids an extra instance creation
// for the purposes of cloning...
if ( bindings != null )
{
result = LifecycleUtils.cloneBindings( bindings );
}
else
{
result = new LifecycleBindings();
}
for ( Iterator it = planModifiers.iterator(); it.hasNext(); )
{
BuildPlanModifier modifier = (BuildPlanModifier) it.next();
result = modifier.modifyBindings( result );
}
return result;
return listBuildPlan( mojos, extendedInfo );
}
/**
* Render an entire build plan to a String.
* If extendedInfo == true, include each MojoBinding's configuration in the output.
* Render a list containing the MojoBinding instances for an entire build plan to a String. If extendedInfo == true,
* include each MojoBinding's configuration in the output.
*/
public static String listBuildPlan( BuildPlan plan, MavenProject project, LifecycleBindingManager lifecycleBindingManager, boolean extendedInfo )
throws LifecycleSpecificationException, LifecyclePlannerException, LifecycleLoaderException
{
List mojoBindings = plan.getPlanMojoBindings( project, lifecycleBindingManager );
return listBuildPlan( mojoBindings, extendedInfo );
}
/**
* Render a list containing the MojoBinding instances for an entire build plan to a String.
* If extendedInfo == true, include each MojoBinding's configuration in the output.
*/
public static String listBuildPlan( List mojoBindings, boolean extendedInfo )
public static String listBuildPlan( final List mojoBindings, final boolean extendedInfo )
throws LifecycleSpecificationException, LifecyclePlannerException
{
StringBuffer listing = new StringBuffer();
@ -119,7 +83,7 @@ public final class BuildPlanUtils
{
listing.append( ' ' ).append( formatMojoListing( binding, indentLevel, extendedInfo ) );
}
indentLevel++;
}
else
@ -135,10 +99,10 @@ public final class BuildPlanUtils
}
/**
* Append a newline character, add the next line's number, and indent the new line to the
* appropriate level (which tracks separate forked executions).
* Append a newline character, add the next line's number, and indent the new line to the appropriate level (which
* tracks separate forked executions).
*/
private static void newListingLine( StringBuffer listing, int indentLevel, int counter )
private static void newListingLine( final StringBuffer listing, final int indentLevel, final int counter )
{
listing.append( '\n' );
@ -155,10 +119,10 @@ public final class BuildPlanUtils
}
/**
* Format a single MojoBinding for inclusion in a build plan listing. If extendedInfo == true,
* include the MojoBinding's configuration in the output.
* Format a single MojoBinding for inclusion in a build plan listing. If extendedInfo == true, include the
* MojoBinding's configuration in the output.
*/
public static String formatMojoListing( MojoBinding binding, int indentLevel, boolean extendedInfo )
public static String formatMojoListing( final MojoBinding binding, final int indentLevel, final boolean extendedInfo )
{
StringBuffer listing = new StringBuffer();
@ -169,7 +133,8 @@ public final class BuildPlanUtils
{
listing.append( "\nOrigin: " ).append( binding.getOrigin() );
listing.append( "\nConfiguration:\n\t" ).append(
String.valueOf( binding.getConfiguration() ).replaceAll( "\\n",
String.valueOf( binding.getConfiguration() ).replaceAll(
"\\n",
"\n\t" ) ).append(
'\n' );
}

View File

@ -7,14 +7,13 @@ import org.apache.maven.project.MavenProject;
import java.util.List;
/**
* Responsible for creating a plan of execution for a given project and list of tasks. This build plan
* consists of MojoBinding instances that carry all the information necessary to execute a mojo,
* including configuration from the POM and other sources. NOTE: the build plan may be constructed
* of a main lifecycle binding-set, plus any number of lifecycle modifiers and direct-invocation
* modifiers, to handle cases of forked execution.
* Responsible for creating a plan of execution for a given project and list of tasks. This build plan consists of
* MojoBinding instances that carry all the information necessary to execute a mojo, including configuration from the
* POM and other sources. NOTE: the build plan may be constructed of a main lifecycle binding-set, plus any number of
* lifecycle modifiers and direct-invocation modifiers, to handle cases of forked execution.
*
* @author jdcasey
*
*
*/
public interface BuildPlanner
{

View File

@ -8,7 +8,6 @@ import org.apache.maven.lifecycle.binding.LifecycleBindingManager;
import org.apache.maven.lifecycle.binding.MojoBindingFactory;
import org.apache.maven.lifecycle.model.LifecycleBindings;
import org.apache.maven.lifecycle.model.MojoBinding;
import org.apache.maven.lifecycle.model.Phase;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.loader.PluginLoader;
@ -17,21 +16,20 @@ import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.logging.LogEnabled;
import org.codehaus.plexus.logging.Logger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
/**
* Responsible for creating a plan of execution for a given project and list of tasks. This build plan
* consists of MojoBinding instances that carry all the information necessary to execute a mojo,
* including configuration from the POM and other sources. NOTE: the build plan may be constructed
* of a main lifecycle binding-set, plus any number of lifecycle modifiers and direct-invocation
* modifiers, to handle cases of forked execution.
* Responsible for creating a plan of execution for a given project and list of tasks. This build plan consists of
* MojoBinding instances that carry all the information necessary to execute a mojo, including configuration from the
* POM and other sources. NOTE: the build plan may be constructed of a main lifecycle binding-set, plus any number of
* lifecycle modifiers and direct-invocation modifiers, to handle cases of forked execution.
*
* @author jdcasey
*
*
*/
public class DefaultBuildPlanner
implements BuildPlanner, LogEnabled
@ -48,159 +46,177 @@ public class DefaultBuildPlanner
/**
* Orchestrates construction of the build plan which will be used by the user of LifecycleExecutor.
*/
public BuildPlan constructBuildPlan( List tasks, MavenProject project )
public BuildPlan constructBuildPlan( final List tasks, final MavenProject project )
throws LifecycleLoaderException, LifecycleSpecificationException, LifecyclePlannerException
{
LifecycleBindings defaultBindings = lifecycleBindingManager.getDefaultBindings( project );
LifecycleBindings packagingBindings = lifecycleBindingManager.getBindingsForPackaging( project );
LifecycleBindings projectBindings = lifecycleBindingManager.getProjectCustomBindings( project );
LifecycleBindings merged = LifecycleUtils.mergeBindings( packagingBindings, projectBindings, defaultBindings, true, false );
BuildPlan plan = new BuildPlan( packagingBindings, projectBindings, defaultBindings, tasks );
// foreach task, find the binding list from the merged lifecycle-bindings.
// if the binding list is a super-set of a previous task, forget the previous task/binding
// list, and use the new one.
// if the binding list is null, treat it like a one-off mojo invocation, and parse/validate
// that it can be called as such.
// as binding lists accumulate, push them onto an aggregated "plan" listing...
BuildPlan plan = new LifecycleBuildPlan( tasks, merged );
initializeDirectInvocations( plan, project );
// Inject forked lifecycles as plan modifiers for each mojo that has @execute in it.
addForkedLifecycleModifiers( plan, merged, project, tasks );
addReportingLifecycleModifiers( plan, merged, project, tasks );
addForkedLifecycleModifiers( plan, project );
addReportingLifecycleModifiers( plan, project );
// TODO: Inject relative-ordered project/plugin executions as plan modifiers.
return plan;
}
public void enableLogging( Logger logger )
private void initializeDirectInvocations( final BuildPlan plan, final MavenProject project )
throws LifecycleSpecificationException, LifecycleLoaderException
{
List tasks = plan.getTasks();
for ( Iterator it = tasks.iterator(); it.hasNext(); )
{
String task = (String) it.next();
if ( !LifecycleUtils.isValidPhaseName( task ) )
{
MojoBinding binding = mojoBindingFactory.parseMojoBinding( task, project, true );
plan.addDirectInvocationBinding( task, binding );
}
}
}
public void enableLogging( final Logger logger )
{
this.logger = logger;
}
/**
* Traverses all MojoBinding instances discovered from the POM and its packaging-mappings, and
* orchestrates the process of injecting any modifiers that are necessary to accommodate forked
* execution.
* Traverses all MojoBinding instances discovered from the POM and its packaging-mappings, and orchestrates the
* process of injecting any modifiers that are necessary to accommodate forked execution.
*/
private void addForkedLifecycleModifiers( ModifiablePlanElement planElement, LifecycleBindings lifecycleBindings,
MavenProject project, List tasks )
private void addForkedLifecycleModifiers( final BuildPlan plan, final MavenProject project )
throws LifecyclePlannerException, LifecycleSpecificationException, LifecycleLoaderException
{
List planBindings = lifecycleBindingManager.assembleMojoBindingList( tasks, lifecycleBindings, project );
List planBindings = plan.renderExecutionPlan( new Stack() );
plan.resetExecutionProgress();
for ( Iterator it = planBindings.iterator(); it.hasNext(); )
{
MojoBinding mojoBinding = (MojoBinding) it.next();
findForkModifiers( mojoBinding, planElement, lifecycleBindings, project );
findForkModifiers( mojoBinding, plan, project );
}
}
private void findForkModifiers( MojoBinding mojoBinding, ModifiablePlanElement planElement,
LifecycleBindings lifecycleBindings, MavenProject project )
private void findForkModifiers( final MojoBinding mojoBinding, final BuildPlan plan, final MavenProject project )
throws LifecyclePlannerException, LifecycleSpecificationException, LifecycleLoaderException
{
PluginDescriptor pluginDescriptor;
PluginDescriptor pluginDescriptor = null;
try
{
pluginDescriptor = pluginLoader.loadPlugin( mojoBinding, project );
}
catch ( PluginLoaderException e )
{
throw new LifecyclePlannerException( e.getMessage(), e );
String message =
"Failed to load plugin: " + MojoBindingUtils.createPluginKey( mojoBinding )
+ ". Adding to late-bound plugins list.\nReason: " + e.getMessage();
if ( logger.isDebugEnabled() )
{
logger.debug( message, e );
}
else
{
logger.warn( message );
}
plan.addLateBoundMojo( mojoBinding );
}
if ( pluginDescriptor == null )
{
return;
}
MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( mojoBinding.getGoal() );
if ( mojoDescriptor == null )
{
throw new LifecyclePlannerException( "Mojo: " + mojoBinding.getGoal() + " does not exist in plugin: "
+ pluginDescriptor.getId() + "." );
+ pluginDescriptor.getId() + "." );
}
findForkModifiers( mojoBinding, pluginDescriptor, planElement, lifecycleBindings, project, new LinkedList() );
findForkModifiers( mojoBinding, pluginDescriptor, plan, project );
}
/**
* Traverses all MojoBinding instances discovered from the POM and its packaging-mappings, and
* orchestrates the process of injecting any modifiers that are necessary to accommodate mojos
* that require access to the project's configured reports.
* Traverses all MojoBinding instances discovered from the POM and its packaging-mappings, and orchestrates the
* process of injecting any modifiers that are necessary to accommodate mojos that require access to the project's
* configured reports.
*/
private void addReportingLifecycleModifiers( ModifiablePlanElement planElement, LifecycleBindings lifecycleBindings,
MavenProject project, List tasks )
private void addReportingLifecycleModifiers( final BuildPlan plan, final MavenProject project )
throws LifecyclePlannerException, LifecycleSpecificationException, LifecycleLoaderException
{
List planBindings = lifecycleBindingManager.assembleMojoBindingList( tasks, lifecycleBindings, project );
List planBindings = plan.renderExecutionPlan( new Stack() );
plan.resetExecutionProgress();
for ( Iterator it = planBindings.iterator(); it.hasNext(); )
{
MojoBinding mojoBinding = (MojoBinding) it.next();
PluginDescriptor pluginDescriptor;
PluginDescriptor pluginDescriptor = null;
try
{
pluginDescriptor = pluginLoader.loadPlugin( mojoBinding, project );
}
catch ( PluginLoaderException e )
{
throw new LifecyclePlannerException( e.getMessage(), e );
String message =
"Failed to load plugin: " + MojoBindingUtils.createPluginKey( mojoBinding )
+ ". Adding to late-bound plugins list.\nReason: " + e.getMessage();
if ( logger.isDebugEnabled() )
{
logger.debug( message, e );
}
else
{
logger.warn( message );
}
plan.addLateBoundMojo( mojoBinding );
}
if ( pluginDescriptor == null )
{
continue;
}
MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( mojoBinding.getGoal() );
if ( mojoDescriptor == null )
{
throw new LifecyclePlannerException( "Mojo: " + mojoBinding.getGoal() + " does not exist in plugin: "
+ pluginDescriptor.getId() + "." );
+ pluginDescriptor.getId() + "." );
}
if ( mojoDescriptor.isRequiresReports() )
{
List reportBindings = lifecycleBindingManager.getReportBindings( project );
// findForkModifiers( mojoBinding, pluginDescriptor, planElement, lifecycleBindings,
// project, forkingBindings, tasks );
for ( Iterator reportBindingIt = reportBindings.iterator(); reportBindingIt.hasNext(); )
{
MojoBinding reportBinding = (MojoBinding) reportBindingIt.next();
PluginDescriptor pd;
try
{
pd = pluginLoader.loadReportPlugin( mojoBinding, project );
pluginLoader.loadReportPlugin( mojoBinding, project );
}
catch ( PluginLoaderException e )
{
throw new LifecyclePlannerException( "Failed to load report-plugin descriptor for: "
+ MojoBindingUtils.toString( reportBinding ) + ". Reason: " + e.getMessage(), e );
}
// findForkModifiers( reportBinding, planElement, lifecycleBindings, project );
}
Phase phase = LifecycleUtils.findPhaseForMojoBinding( mojoBinding, lifecycleBindings, true );
if ( phase == null )
{
if ( planElement instanceof DirectInvocationOriginElement )
{
DirectInvocationModifier modder = new SimpleDirectInvocationModifier( mojoBinding, reportBindings );
( (DirectInvocationOriginElement) planElement ).addDirectInvocationModifier( modder );
}
else
{
throw new LifecyclePlannerException( "Cannot inject reports for direct invocation: "
+ MojoBindingUtils.toString( mojoBinding )
+ "; current plan element does not accept direct-invocation modifiers." );
+ MojoBindingUtils.toString( reportBinding )
+ ". Reason: " + e.getMessage(), e );
}
}
else
{
BuildPlanModifier modder = new ReportingPlanModifier( mojoBinding, reportBindings );
planElement.addModifier( modder );
}
plan.addForkedExecution( mojoBinding, reportBindings );
// NOTE: the first sighting of a mojo requiring reports should satisfy this condition.
// therefore, we can break out as soon as we find one.
@ -210,159 +226,38 @@ public class DefaultBuildPlanner
}
/**
* Explores a single MojoBinding, and injects any necessary plan modifiers to accommodate any
* of the three types of forked execution, along with any new mojos/lifecycles that entails.
* Explores a single MojoBinding, and injects any necessary plan modifiers to accommodate any of the three types of
* forked execution, along with any new mojos/lifecycles that entails.
*/
private void findForkModifiers( MojoBinding mojoBinding, PluginDescriptor pluginDescriptor,
ModifiablePlanElement planElement, LifecycleBindings mergedBindings, MavenProject project,
LinkedList forkingBindings )
private void findForkModifiers( final MojoBinding mojoBinding, final PluginDescriptor pluginDescriptor,
final BuildPlan plan, final MavenProject project )
throws LifecyclePlannerException, LifecycleSpecificationException, LifecycleLoaderException
{
forkingBindings.addLast( mojoBinding );
String referencingGoal = mojoBinding.getGoal();
try
MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( referencingGoal );
if ( mojoDescriptor.getExecuteGoal() != null )
{
String referencingGoal = mojoBinding.getGoal();
MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( referencingGoal );
if ( mojoDescriptor.getExecuteGoal() != null )
{
recurseSingleMojoFork( mojoBinding, pluginDescriptor, planElement, mergedBindings, project, forkingBindings );
}
else if ( mojoDescriptor.getExecutePhase() != null )
{
recursePhaseMojoFork( mojoBinding, pluginDescriptor, planElement, mergedBindings, project, forkingBindings );
}
recurseSingleMojoFork( mojoBinding, pluginDescriptor, plan, project );
}
finally
else if ( mojoDescriptor.getExecutePhase() != null )
{
forkingBindings.removeLast();
recursePhaseMojoFork( mojoBinding, pluginDescriptor, plan, project );
}
}
/**
* Handles exploration of a single-mojo forked execution for further forkings, and also performs
* the actual build-plan modification for that single-mojo forked execution.
*/
private void modifyBuildPlanForForkedDirectInvocation( MojoBinding invokedBinding, MojoBinding invokedVia,
PluginDescriptor pluginDescriptor, ModifiablePlanElement planElement,
LifecycleBindings mergedBindings, MavenProject project,
LinkedList forkingBindings )
throws LifecyclePlannerException, LifecycleSpecificationException, LifecycleLoaderException
{
if ( planElement instanceof DirectInvocationOriginElement )
{
List noTasks = Collections.EMPTY_LIST;
LifecycleBindings forkedBindings = new LifecycleBindings();
LifecycleBuildPlan forkedPlan = new LifecycleBuildPlan( noTasks, forkedBindings );
forkingBindings.addLast( invokedBinding );
try
{
findForkModifiers( invokedBinding, pluginDescriptor, forkedPlan, forkedBindings, project, forkingBindings );
}
finally
{
forkingBindings.removeLast();
}
List forkedMojos = new ArrayList();
forkedMojos.addAll( lifecycleBindingManager.assembleMojoBindingList( noTasks, forkedBindings, project ) );
forkedMojos.add( invokedBinding );
DirectInvocationModifier modifier = new ForkedDirectInvocationModifier( invokedVia, forkedMojos );
( (DirectInvocationOriginElement) planElement ).addDirectInvocationModifier( modifier );
}
else
{
throw new LifecyclePlannerException( "Mojo: " + MojoBindingUtils.toString( invokedVia )
+ " is not bound to the lifecycle; you cannot attach this mojo to a build-plan modifier." );
}
}
/**
* Handles exploration of a lifecycle-based forked execution for further forkings, and also performs
* the actual build-plan modification for that lifecycle-based forked execution.
*/
private void modifyBuildPlanForForkedLifecycle( MojoBinding mojoBinding, PluginDescriptor pluginDescriptor,
ModifiablePlanElement planElement, LifecycleBindings bindings,
MavenProject project, LinkedList forkingBindings )
throws LifecycleSpecificationException, LifecyclePlannerException, LifecycleLoaderException
{
MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( mojoBinding.getGoal() );
String phase = mojoDescriptor.getExecutePhase();
List forkedPhaseBindingList = lifecycleBindingManager.assembleMojoBindingList( Collections.singletonList( phase ),
bindings, project );
ModifiablePlanElement mpe;
// setup the ModifiablePlanElement, into which we'll recurse to find further modifications.
if ( LifecycleUtils.findPhaseForMojoBinding( mojoBinding, bindings, true ) != null )
{
mpe = new ForkPlanModifier( mojoBinding, forkedPhaseBindingList );
}
else if ( planElement instanceof BuildPlan )
{
mpe = new SubLifecycleBuildPlan( phase, bindings );
}
else
{
throw new LifecyclePlannerException( "Mojo: " + MojoBindingUtils.toString( mojoBinding )
+ " is not bound to the lifecycle; you cannot attach this mojo to a build-plan modifier." );
}
// recurse, to find further modifications, using the ModifiablePlanElement from above, along
// with the modified task list (which doesn't contain the direct-invocation task that landed
// us here...
for ( Iterator it = forkedPhaseBindingList.iterator(); it.hasNext(); )
{
MojoBinding forkedBinding = (MojoBinding) it.next();
PluginDescriptor forkedPluginDescriptor;
try
{
forkedPluginDescriptor = pluginLoader.loadPlugin( forkedBinding, project );
}
catch ( PluginLoaderException e )
{
throw new LifecyclePlannerException( e.getMessage(), e );
}
findForkModifiers( forkedBinding, forkedPluginDescriptor, mpe, bindings, project, forkingBindings );
}
// now that we've discovered any deeper modifications, add the current MPE to the parent MPE
// in the appropriate location.
if ( LifecycleUtils.findPhaseForMojoBinding( mojoBinding, bindings, true ) != null )
{
planElement.addModifier( (BuildPlanModifier) mpe );
}
else if ( planElement instanceof DirectInvocationOriginElement )
{
List planMojoBindings = ( (BuildPlan) mpe ).getPlanMojoBindings( project, lifecycleBindingManager );
ForkedDirectInvocationModifier modifier = new ForkedDirectInvocationModifier( mojoBinding, planMojoBindings );
( (DirectInvocationOriginElement) planElement ).addDirectInvocationModifier( modifier );
}
}
/**
* Constructs the lifecycle bindings used to execute a particular fork, given the forking mojo
* binding. If the mojo binding specifies a lifecycle overlay, this method will add that into
* the forked lifecycle, and calculate the bindings to inject based on the phase in that new
* lifecycle which should be executed.
* Constructs the lifecycle bindings used to execute a particular fork, given the forking mojo binding. If the mojo
* binding specifies a lifecycle overlay, this method will add that into the forked lifecycle, and calculate the
* bindings to inject based on the phase in that new lifecycle which should be executed.
*
* Hands off to the {@link DefaultBuildPlanner#modifyBuildPlanForForkedLifecycle(MojoBinding, PluginDescriptor, ModifiablePlanElement, LifecycleBindings, MavenProject, LinkedList, List)}
* Hands off to the
* {@link DefaultBuildPlanner#modifyBuildPlanForForkedLifecycle(MojoBinding, PluginDescriptor, ModifiablePlanElement, LifecycleBindings, MavenProject, LinkedList, List)}
* method to handle the actual plan modification.
*/
private void recursePhaseMojoFork( MojoBinding mojoBinding, PluginDescriptor pluginDescriptor,
ModifiablePlanElement planElement, LifecycleBindings mergedBindings, MavenProject project,
LinkedList forkingBindings )
private void recursePhaseMojoFork( final MojoBinding mojoBinding, final PluginDescriptor pluginDescriptor,
final BuildPlan plan, final MavenProject project )
throws LifecyclePlannerException, LifecycleSpecificationException, LifecycleLoaderException
{
String referencingGoal = mojoBinding.getGoal();
@ -376,48 +271,44 @@ public class DefaultBuildPlanner
return;
}
if ( LifecycleUtils.findLifecycleBindingForPhase( phase, mergedBindings ) == null )
if ( !LifecycleUtils.isValidPhaseName( phase ) )
{
throw new LifecyclePlannerException( "Cannot find lifecycle for phase: " + phase );
}
LifecycleBindings cloned;
if ( mojoDescriptor.getExecuteLifecycle() != null )
{
String executeLifecycle = mojoDescriptor.getExecuteLifecycle();
BuildPlan clonedPlan = plan.copy( Collections.singletonList( phase ) );
String executeLifecycle = mojoDescriptor.getExecuteLifecycle();
if ( executeLifecycle != null )
{
LifecycleBindings overlayBindings;
try
{
overlayBindings = lifecycleBindingManager.getPluginLifecycleOverlay( pluginDescriptor, executeLifecycle, project );
overlayBindings =
lifecycleBindingManager.getPluginLifecycleOverlay( pluginDescriptor, executeLifecycle, project );
}
catch ( LifecycleLoaderException e )
{
throw new LifecyclePlannerException( "Failed to load overlay lifecycle: " + executeLifecycle + ". Reason: "
+ e.getMessage(), e );
throw new LifecyclePlannerException( "Failed to load overlay lifecycle: " + executeLifecycle
+ ". Reason: " + e.getMessage(), e );
}
cloned = LifecycleUtils.cloneBindings( mergedBindings );
cloned = LifecycleUtils.mergeBindings( overlayBindings, cloned, null, true, true );
}
else
{
cloned = LifecycleUtils.cloneBindings( mergedBindings );
clonedPlan.addLifecycleOverlay( overlayBindings );
}
LifecycleUtils.removeMojoBindings( forkingBindings, cloned, false );
plan.addForkedExecution( mojoBinding, clonedPlan );
modifyBuildPlanForForkedLifecycle( mojoBinding, pluginDescriptor, planElement, cloned, project, forkingBindings );
addForkedLifecycleModifiers( clonedPlan, project );
}
/**
* Retrieves the information necessary to create a new MojoBinding for a single-mojo forked
* execution, then hands off to the {@link DefaultBuildPlanner#modifyBuildPlanForForkedDirectInvocation(MojoBinding, MojoBinding, PluginDescriptor, ModifiablePlanElement, LifecycleBindings, MavenProject, LinkedList, List)}
* Retrieves the information necessary to create a new MojoBinding for a single-mojo forked execution, then hands
* off to the
* {@link DefaultBuildPlanner#modifyBuildPlanForForkedDirectInvocation(MojoBinding, MojoBinding, PluginDescriptor, ModifiablePlanElement, LifecycleBindings, MavenProject, LinkedList, List)}
* method to actually inject the modification.
*/
private void recurseSingleMojoFork( MojoBinding mojoBinding, PluginDescriptor pluginDescriptor,
ModifiablePlanElement planElement, LifecycleBindings mergedBindings,
MavenProject project, LinkedList forkingBindings )
private void recurseSingleMojoFork( final MojoBinding mojoBinding, final PluginDescriptor pluginDescriptor,
final BuildPlan plan, final MavenProject project )
throws LifecyclePlannerException, LifecycleSpecificationException, LifecycleLoaderException
{
String referencingGoal = mojoBinding.getGoal();
@ -435,20 +326,16 @@ public class DefaultBuildPlanner
if ( otherDescriptor == null )
{
throw new LifecyclePlannerException( "Mojo: " + executeGoal + " (referenced by: " + referencingGoal
+ ") does not exist in plugin: " + pluginDescriptor.getId() + "." );
+ ") does not exist in plugin: " + pluginDescriptor.getId() + "." );
}
MojoBinding binding = mojoBindingFactory.createMojoBinding( pluginDescriptor.getGroupId(),
pluginDescriptor.getArtifactId(),
pluginDescriptor.getVersion(), executeGoal, project );
MojoBinding binding =
mojoBindingFactory.createMojoBinding( pluginDescriptor.getGroupId(), pluginDescriptor.getArtifactId(),
pluginDescriptor.getVersion(), executeGoal, project );
binding.setOrigin( "Forked from " + referencingGoal );
if ( !LifecycleUtils.isMojoBindingPresent( binding, forkingBindings, false ) )
{
modifyBuildPlanForForkedDirectInvocation( binding, mojoBinding, pluginDescriptor, planElement, mergedBindings,
project, forkingBindings );
}
plan.addForkedExecution( mojoBinding, Collections.singletonList( binding ) );
}
}

View File

@ -1,32 +0,0 @@
package org.apache.maven.lifecycle.plan;
import org.apache.maven.lifecycle.binding.LifecycleBindingManager;
import org.apache.maven.lifecycle.model.LifecycleBindings;
import org.apache.maven.lifecycle.model.MojoBinding;
import org.apache.maven.project.MavenProject;
import java.util.List;
/**
* Modifier that alters a build plan to substitute a set of MojoBindings in place of a single,
* direct-invocation MojoBinding. These bindings are not impacted by {@link BuildPlanModifier}s,
* since they don't exist in a {@link LifecycleBindings} instance.
*
* @author jdcasey
*
*/
public interface DirectInvocationModifier
{
/**
* The MojoBinding which should be modified.
*/
MojoBinding getBindingToModify();
/**
* Return the list of MojoBindings which should replace the modified binding in the master
* build plan.
*/
List getModifiedBindings( MavenProject project, LifecycleBindingManager bindingManager );
}

View File

@ -1,17 +0,0 @@
package org.apache.maven.lifecycle.plan;
/**
* Instantiates MojoBindings for direct invocation, which may be subject to modification.
*
* @author jdcasey
*
*/
public interface DirectInvocationOriginElement
{
/**
* Add a new direct-invocation binding modifier.
*/
void addDirectInvocationModifier( DirectInvocationModifier modifier );
}

View File

@ -1,113 +0,0 @@
package org.apache.maven.lifecycle.plan;
import org.apache.maven.lifecycle.LifecycleUtils;
import org.apache.maven.lifecycle.model.LifecycleBindings;
import org.apache.maven.lifecycle.model.MojoBinding;
import org.apache.maven.lifecycle.model.Phase;
import org.apache.maven.lifecycle.statemgmt.StateManagementUtils;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Inject a list of forked-execution bindings at the point where the modification point is bound to
* the supplied LifecycleBindings, bracketed by special mojo bindings to control the forked-execution
* context.
*
* @author jdcasey
*
*/
public class ForkPlanModifier
implements BuildPlanModifier
{
private final MojoBinding modificationPoint;
private List planModifiers = new ArrayList();
private final List mojoBindings;
public ForkPlanModifier( MojoBinding modificationPoint, List mojoBindings )
{
this.modificationPoint = modificationPoint;
this.mojoBindings = mojoBindings;
}
/**
* Retrieve the MojoBinding which serves as the injection point for the forked bindings.
*/
public MojoBinding getModificationPoint()
{
return modificationPoint;
}
/**
* Modify the LifeycleBindings from a BuildPlan by locating the modification point MojoBinding,
* and prepending the forked-execution bindings in the plan, bracketed by mojos that control the
* forked-execution context.
*/
public LifecycleBindings modifyBindings( LifecycleBindings bindings )
throws LifecyclePlannerException
{
Phase phase = LifecycleUtils.findPhaseForMojoBinding( getModificationPoint(), bindings, true );
String modificationKey = LifecycleUtils.createMojoBindingKey( getModificationPoint(), true );
if ( phase == null )
{
throw new LifecyclePlannerException( "Failed to modify plan. No phase found containing mojoBinding: "
+ modificationKey );
}
int stopIndex = -1;
int insertionIndex = -1;
List phaseBindings = phase.getBindings();
for ( int i = 0; i < phaseBindings.size(); i++ )
{
MojoBinding candidate = (MojoBinding) phaseBindings.get( i );
String key = LifecycleUtils.createMojoBindingKey( candidate, true );
if ( key.equals( modificationKey ) )
{
insertionIndex = i;
stopIndex = i + 1;
break;
}
}
phaseBindings.add( stopIndex, StateManagementUtils.createClearForkedExecutionMojoBinding() );
phaseBindings.add( insertionIndex, StateManagementUtils.createEndForkedExecutionMojoBinding() );
phaseBindings.addAll( insertionIndex, mojoBindings );
phaseBindings.add( insertionIndex, StateManagementUtils.createStartForkedExecutionMojoBinding() );
phase.setBindings( phaseBindings );
for ( Iterator it = planModifiers.iterator(); it.hasNext(); )
{
BuildPlanModifier modifier = (BuildPlanModifier) it.next();
modifier.modifyBindings( bindings );
}
return bindings;
}
/**
* Add a new modifier to further adjust the LifecycleBindings which are modified here.
*/
public void addModifier( BuildPlanModifier planModifier )
{
planModifiers.add( planModifier );
}
/**
* Return true if this modifier itself has modifiers.
*/
public boolean hasModifiers()
{
return !planModifiers.isEmpty();
}
}

View File

@ -1,56 +0,0 @@
package org.apache.maven.lifecycle.plan;
import org.apache.maven.lifecycle.binding.LifecycleBindingManager;
import org.apache.maven.lifecycle.model.MojoBinding;
import org.apache.maven.lifecycle.statemgmt.StateManagementUtils;
import org.apache.maven.project.MavenProject;
import java.util.ArrayList;
import java.util.List;
/**
* Inject a list of MojoBindings in place of the forking binding, bracketing the forked bindings with
* special mojos to control the forked-execution context.
*
* @author jdcasey
*
*/
public class ForkedDirectInvocationModifier
implements DirectInvocationModifier
{
private final List forkedBindings;
private final MojoBinding forkingBinding;
public ForkedDirectInvocationModifier( MojoBinding forkingBinding, List forkedBindings )
{
this.forkingBinding = forkingBinding;
this.forkedBindings = forkedBindings;
}
/**
* Return a list containing forked-execution context control MojoBindings, the forked-execution
* bindings themselves, and finally the binding that forked off a new execution branch.
*/
public List getModifiedBindings( MavenProject project, LifecycleBindingManager bindingManager )
{
List result = new ArrayList();
result.add( StateManagementUtils.createStartForkedExecutionMojoBinding() );
result.addAll( forkedBindings );
result.add( StateManagementUtils.createEndForkedExecutionMojoBinding() );
result.add( forkingBinding );
result.add( StateManagementUtils.createClearForkedExecutionMojoBinding() );
return result;
}
/**
* Return the MojoBinding that forks execution to include the bindings in this modifier.
*/
public MojoBinding getBindingToModify()
{
return forkingBinding;
}
}

View File

@ -1,91 +0,0 @@
package org.apache.maven.lifecycle.plan;
import org.apache.maven.lifecycle.LifecycleLoaderException;
import org.apache.maven.lifecycle.LifecycleSpecificationException;
import org.apache.maven.lifecycle.LifecycleUtils;
import org.apache.maven.lifecycle.binding.LifecycleBindingManager;
import org.apache.maven.lifecycle.model.LifecycleBindings;
import org.apache.maven.project.MavenProject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Construct a list of MojoBinding instances that accomplish all of the tasks specified. For lifecycle
* phases, construct a list of mojos to execute up to and including the specified phase, and add them
* to the list. For direct invocations, construct a new MojoBinding instance and add it to the list.
*
* All of these bindings are subject to lifecycle modifications due to forking, reporting, or other
* factors, and also to forked-execution modification of direct invocations.
*
* @author jdcasey
*
*/
public class LifecycleBuildPlan
implements BuildPlan, DirectInvocationOriginElement
{
private final List tasks;
private final LifecycleBindings lifecycleBindings;
private List planModifiers = new ArrayList();
private Map directInvocationModifiers = new HashMap();
public LifecycleBuildPlan( List tasks, LifecycleBindings lifecycleBindings )
{
this.tasks = tasks;
this.lifecycleBindings = lifecycleBindings;
}
/**
* Build the master execution list necessary to accomplish the specified tasks, given the
* specified set of mojo bindings to different parts of the lifecycle.
*/
public List getPlanMojoBindings( MavenProject project, LifecycleBindingManager bindingManager )
throws LifecycleSpecificationException, LifecyclePlannerException, LifecycleLoaderException
{
LifecycleBindings cloned = BuildPlanUtils.modifyPlanBindings( lifecycleBindings, planModifiers );
return bindingManager.assembleMojoBindingList( tasks, cloned, directInvocationModifiers, project );
}
/**
* Retrieve the set of tasks that this build plan is responsible for.
*/
public List getTasks()
{
return tasks;
}
/**
* Add a new build-plan modifier to inject reporting, forked-execution, or other altered behavior
* into the "vanilla" lifecycle that was specified at instance construction.
*/
public void addModifier( BuildPlanModifier planModifier )
{
planModifiers.add( planModifier );
}
/**
* Return true if build-plan modifiers exist (these are lifecycle-only modifiers, not direct
* invocation modifiers).
*/
public boolean hasModifiers()
{
return !planModifiers.isEmpty();
}
/**
* Add a new modifier for a direct-invocation MojoBinding in the build plan resulting from this
* instance.
*/
public void addDirectInvocationModifier( DirectInvocationModifier modifier )
{
directInvocationModifiers.put( LifecycleUtils.createMojoBindingKey( modifier.getBindingToModify(), true ), modifier );
}
}

View File

@ -1,23 +0,0 @@
package org.apache.maven.lifecycle.plan;
/**
* Any element of a build plan that contains or handles a LifecycleBindings instance which is subject
* to modification.
*
* @author jdcasey
*
*/
public interface ModifiablePlanElement
{
/**
* Add a new lifecycle modifier to this build-plan element.
*/
void addModifier( BuildPlanModifier planModifier );
/**
* Return true if this element has lifecycle modifiers
*/
boolean hasModifiers();
}

View File

@ -1,94 +0,0 @@
package org.apache.maven.lifecycle.plan;
import org.apache.maven.lifecycle.LifecycleUtils;
import org.apache.maven.lifecycle.model.LifecycleBindings;
import org.apache.maven.lifecycle.model.MojoBinding;
import org.apache.maven.lifecycle.model.Phase;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Inject the MojoBindings necessary to execute and make available the report instances that another
* mojo in the build plan needs.
*
* @author jdcasey
*
*/
public class ReportingPlanModifier
implements BuildPlanModifier
{
private List planModifiers = new ArrayList();
private final MojoBinding targetMojoBinding;
private final List reportBindings;
public ReportingPlanModifier( MojoBinding mojoBinding, List reportBindings )
{
this.targetMojoBinding = mojoBinding;
this.reportBindings = reportBindings;
}
/**
* Find the mojo that requested reports, and inject the reporting MojoBinding instances just
* ahead of it in the lifecycle bindings.
*/
public LifecycleBindings modifyBindings( LifecycleBindings bindings )
throws LifecyclePlannerException
{
Phase phase = LifecycleUtils.findPhaseForMojoBinding( targetMojoBinding, bindings, true );
String modificationKey = LifecycleUtils.createMojoBindingKey( targetMojoBinding, true );
if ( phase == null )
{
throw new LifecyclePlannerException( "Failed to modify plan. No phase found containing mojoBinding: "
+ modificationKey );
}
int insertionIndex = -1;
List phaseBindings = phase.getBindings();
for ( int i = 0; i < phaseBindings.size(); i++ )
{
MojoBinding candidate = (MojoBinding) phaseBindings.get( i );
String key = LifecycleUtils.createMojoBindingKey( candidate, true );
if ( key.equals( modificationKey ) )
{
insertionIndex = i;
break;
}
}
phaseBindings.addAll( insertionIndex, reportBindings );
phase.setBindings( phaseBindings );
for ( Iterator it = planModifiers.iterator(); it.hasNext(); )
{
BuildPlanModifier modifier = (BuildPlanModifier) it.next();
modifier.modifyBindings( bindings );
}
return bindings;
}
/**
* Add further lifecycle modifications to this report-injecting modifier.
*/
public void addModifier( BuildPlanModifier planModifier )
{
planModifiers.add( planModifier );
}
/**
* Return true if this report-injecting modifier contains further modifications for the lifecycle.
*/
public boolean hasModifiers()
{
return !planModifiers.isEmpty();
}
}

View File

@ -1,52 +0,0 @@
package org.apache.maven.lifecycle.plan;
import org.apache.maven.lifecycle.binding.LifecycleBindingManager;
import org.apache.maven.lifecycle.model.MojoBinding;
import org.apache.maven.project.MavenProject;
import java.util.ArrayList;
import java.util.List;
/**
* Inject a list of MojoBindings in place of the forking binding, bracketing the forked bindings with
* special mojos to control the forked-execution context.
*
* @author jdcasey
*
*/
public class SimpleDirectInvocationModifier
implements DirectInvocationModifier
{
private final List reportBindings;
private final MojoBinding targetBinding;
public SimpleDirectInvocationModifier( MojoBinding targetBinding, List reportBindings )
{
this.targetBinding = targetBinding;
this.reportBindings = reportBindings;
}
/**
* Return a list containing forked-execution context control MojoBindings, the forked-execution
* bindings themselves, and finally the binding that forked off a new execution branch.
*/
public List getModifiedBindings( MavenProject project, LifecycleBindingManager bindingManager )
{
List result = new ArrayList();
result.addAll( reportBindings );
result.add( targetBinding );
return result;
}
/**
* Return the MojoBinding that forks execution to include the bindings in this modifier.
*/
public MojoBinding getBindingToModify()
{
return targetBinding;
}
}

View File

@ -1,70 +0,0 @@
package org.apache.maven.lifecycle.plan;
import org.apache.maven.lifecycle.LifecycleLoaderException;
import org.apache.maven.lifecycle.LifecycleSpecificationException;
import org.apache.maven.lifecycle.binding.LifecycleBindingManager;
import org.apache.maven.lifecycle.model.LifecycleBindings;
import org.apache.maven.project.MavenProject;
import java.util.Collections;
import java.util.List;
/**
* Constructs a build plan using a LifecycleBindings instance, but only allowing one phase for that
* lifecycle, as opposed to the parent class which allows a list of tasks (some of which may not be
* lifecycle phases at all).
*
* This build plan cannot produce direct-invocation MojoBindings.
*
* @author jdcasey
*
*/
public class SubLifecycleBuildPlan
implements BuildPlan
{
private LifecycleBuildPlan delegate;
private final String phase;
public SubLifecycleBuildPlan( String phase, LifecycleBindings bindings )
{
this.phase = phase;
delegate = new LifecycleBuildPlan( Collections.singletonList( phase ), bindings );
}
/**
* Retrieve the build plan binding list from the delegate {@link LifecycleBuildPlan} instance,
* and return them.
*/
public List getPlanMojoBindings(MavenProject project, LifecycleBindingManager bindingManager)
throws LifecycleSpecificationException, LifecyclePlannerException, LifecycleLoaderException
{
return delegate.getPlanMojoBindings(project, bindingManager);
}
/**
* Return a list containing a single item: the lifecycle phase that this plan is concerned with
* accomplishing.
*/
public List getTasks()
{
return Collections.singletonList( phase );
}
/**
* Add a build-plan modifier to the delegate {@link LifecycleBuildPlan} instance.
*/
public void addModifier( BuildPlanModifier planModifier )
{
delegate.addModifier( planModifier );
}
/**
* Return true if the delegate {@link LifecycleBuildPlan} instance contains build-plan modifiers.
*/
public boolean hasModifiers()
{
return delegate.hasModifiers();
}
}

View File

@ -0,0 +1,57 @@
package org.apache.maven.lifecycle.statemgmt;
import org.apache.maven.lifecycle.MojoBindingUtils;
import org.apache.maven.lifecycle.binding.MojoBindingFactory;
import org.apache.maven.lifecycle.model.MojoBinding;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.loader.PluginLoader;
import org.apache.maven.plugin.loader.PluginLoaderException;
import org.apache.maven.project.MavenProject;
public class ResolveLateBoundPluginMojo extends AbstractMojo
{
/**
* @component
*/
private PluginLoader pluginLoader;
private String groupId;
private String artifactId;
private String version;
private String goal;
private MavenProject project;
private MojoBindingFactory bindingFactory;
public void execute() throws MojoExecutionException, MojoFailureException
{
MojoBinding binding = bindingFactory.createMojoBinding( groupId, artifactId, version, artifactId, project );
try
{
PluginDescriptor descriptor = pluginLoader.loadPlugin( binding, project );
MojoDescriptor mojoDescriptor = descriptor.getMojo( goal );
if ( mojoDescriptor == null )
{
throw new MojoExecutionException( "Resolved plugin: " + descriptor.getId()
+ " does not contain a mojo called \'" + goal + "\'." );
}
}
catch ( PluginLoaderException e )
{
throw new MojoExecutionException( "Failed to load late-bound plugin: "
+ MojoBindingUtils.createPluginKey( binding ) );
}
}
}

View File

@ -4,11 +4,10 @@ import org.apache.maven.lifecycle.model.MojoBinding;
import org.codehaus.plexus.util.xml.Xpp3Dom;
/**
* Constructs and matches MojoBinding instances that refer to the forked-execution context manager
* mojos.
* Constructs and matches MojoBinding instances that refer to the forked-execution context manager mojos.
*
* @author jdcasey
*
*
*/
public final class StateManagementUtils
{
@ -27,6 +26,8 @@ public final class StateManagementUtils
public static final String CLEAR_FORKED_EXECUTION_GOAL = "clear-fork-context";
public static final String RESOLVE_LATE_BOUND_PLUGIN_GOAL = "resolve-late-bound-plugin";
private static int CURRENT_FORK_ID = 0;
private StateManagementUtils()
@ -34,9 +35,8 @@ public final class StateManagementUtils
}
/**
* Create a new MojoBinding instance that refers to the internal mojo used to setup a new
* forked-execution context. Also, set the configuration to contain the forkId for this new
* context.
* Create a new MojoBinding instance that refers to the internal mojo used to setup a new forked-execution context.
* Also, set the configuration to contain the forkId for this new context.
*/
public static MojoBinding createStartForkedExecutionMojoBinding()
{
@ -49,22 +49,21 @@ public final class StateManagementUtils
binding.setOrigin( ORIGIN );
CURRENT_FORK_ID = (int) System.currentTimeMillis();
Xpp3Dom config = new Xpp3Dom( "configuration" );
Xpp3Dom forkId = new Xpp3Dom( "forkId" );
forkId.setValue( "" + CURRENT_FORK_ID );
config.addChild( forkId );
binding.setConfiguration( config );
return binding;
}
/**
* Create a new MojoBinding instance that refers to the internal mojo used to end a
* forked-execution context. Also, set the configuration to contain the forkId for this new
* context.
* Create a new MojoBinding instance that refers to the internal mojo used to end a forked-execution context. Also,
* set the configuration to contain the forkId for this new context.
*/
public static MojoBinding createEndForkedExecutionMojoBinding()
{
@ -79,18 +78,17 @@ public final class StateManagementUtils
Xpp3Dom config = new Xpp3Dom( "configuration" );
Xpp3Dom forkId = new Xpp3Dom( "forkId" );
forkId.setValue( "" + CURRENT_FORK_ID );
config.addChild( forkId );
binding.setConfiguration( config );
return binding;
}
/**
* Create a new MojoBinding instance that refers to the internal mojo used to cleanup a completed
* forked-execution context. Also, set the configuration to contain the forkId for this new
* context.
* Create a new MojoBinding instance that refers to the internal mojo used to cleanup a completed forked-execution
* context. Also, set the configuration to contain the forkId for this new context.
*/
public static MojoBinding createClearForkedExecutionMojoBinding()
{
@ -105,45 +103,99 @@ public final class StateManagementUtils
Xpp3Dom config = new Xpp3Dom( "configuration" );
Xpp3Dom forkId = new Xpp3Dom( "forkId" );
forkId.setValue( "" + CURRENT_FORK_ID );
config.addChild( forkId );
binding.setConfiguration( config );
return binding;
}
/**
* Return true if the specified MojoBinding refers to the internal mojo used to setup a new
* forked-execution context. This is useful for formatting when listing the build plan, when
* expression of these actual mojo names isn't necessarily useful, and can be confusing.
* Return true if the specified MojoBinding refers to the internal mojo used to setup a new forked-execution
* context. This is useful for formatting when listing the build plan, when expression of these actual mojo names
* isn't necessarily useful, and can be confusing.
*/
public static boolean isForkedExecutionStartMarker( MojoBinding binding )
public static boolean isForkedExecutionStartMarker( final MojoBinding binding )
{
return GROUP_ID.equals( binding.getGroupId() ) && ARTIFACT_ID.equals( binding.getArtifactId() )
&& START_FORKED_EXECUTION_GOAL.equals( binding.getGoal() );
&& START_FORKED_EXECUTION_GOAL.equals( binding.getGoal() );
}
/**
* Return true if the specified MojoBinding refers to the internal mojo used to end a
* forked-execution context. This is useful for formatting when listing the build plan, when
* expression of these actual mojo names isn't necessarily useful, and can be confusing.
* Return true if the specified MojoBinding refers to the internal mojo used to end a forked-execution context. This
* is useful for formatting when listing the build plan, when expression of these actual mojo names isn't
* necessarily useful, and can be confusing.
*/
public static boolean isForkedExecutionEndMarker( MojoBinding binding )
public static boolean isForkedExecutionEndMarker( final MojoBinding binding )
{
return GROUP_ID.equals( binding.getGroupId() ) && ARTIFACT_ID.equals( binding.getArtifactId() )
&& END_FORKED_EXECUTION_GOAL.equals( binding.getGoal() );
&& END_FORKED_EXECUTION_GOAL.equals( binding.getGoal() );
}
/**
* Return true if the specified MojoBinding refers to the internal mojo used to clean up a completed
* forked-execution context. This is useful for formatting when listing the build plan, when
* expression of these actual mojo names isn't necessarily useful, and can be confusing.
* forked-execution context. This is useful for formatting when listing the build plan, when expression of these
* actual mojo names isn't necessarily useful, and can be confusing.
*/
public static boolean isForkedExecutionClearMarker( MojoBinding binding )
public static boolean isForkedExecutionClearMarker( final MojoBinding binding )
{
return GROUP_ID.equals( binding.getGroupId() ) && ARTIFACT_ID.equals( binding.getArtifactId() )
&& CLEAR_FORKED_EXECUTION_GOAL.equals( binding.getGoal() );
&& CLEAR_FORKED_EXECUTION_GOAL.equals( binding.getGoal() );
}
/**
* Create a new MojoBinding instance that refers to the internal mojo used to resolve a late-bound plugin just
* before it is to be used. Also, set the configuration to contain the parameters necessary for this resolution.
*/
public static MojoBinding createResolveLateBoundMojoBinding( final MojoBinding lateBound )
{
MojoBinding binding = new MojoBinding();
binding.setGroupId( GROUP_ID );
binding.setArtifactId( ARTIFACT_ID );
binding.setVersion( VERSION );
binding.setGoal( RESOLVE_LATE_BOUND_PLUGIN_GOAL );
binding.setOrigin( ORIGIN );
Xpp3Dom config = new Xpp3Dom( "configuration" );
Xpp3Dom param = new Xpp3Dom( "groupId" );
param.setValue( lateBound.getGroupId() );
config.addChild( param );
param = new Xpp3Dom( "artifactId" );
param.setValue( lateBound.getArtifactId() );
config.addChild( param );
if ( lateBound.getVersion() != null )
{
param = new Xpp3Dom( "version" );
param.setValue( lateBound.getVersion() );
config.addChild( param );
}
param = new Xpp3Dom( "goal" );
param.setValue( lateBound.getGoal() );
config.addChild( param );
binding.setConfiguration( config );
return binding;
}
/**
* Return true if the specified MojoBinding refers to the internal mojo used to resolve a late-bound mojo. This is
* useful for formatting when listing the build plan, when expression of these actual mojo names isn't necessarily
* useful, and can be confusing.
*/
public static boolean isResolveLateBoundMojoBinding( final MojoBinding binding )
{
return GROUP_ID.equals( binding.getGroupId() ) && ARTIFACT_ID.equals( binding.getArtifactId() )
&& RESOLVE_LATE_BOUND_PLUGIN_GOAL.equals( binding.getGoal() );
}
}

View File

@ -113,5 +113,73 @@
<forkId implementation="int" default-value="-1">${forkId}</forkId>
</configuration>
</mojo>
<mojo>
<goal>resolve-plugin</goal>
<description>Resolve a late-bound plugin during a build, right before it is to be used.</description>
<requiresDirectInvocation>false</requiresDirectInvocation>
<requiresProject>true</requiresProject>
<requiresReports>false</requiresReports>
<aggregator>false</aggregator>
<requiresOnline>false</requiresOnline>
<inheritedByDefault>true</inheritedByDefault>
<implementation>org.apache.maven.lifecycle.statemgmt.ResolveLateBoundPluginMojo</implementation>
<language>java</language>
<instantiationStrategy>per-lookup</instantiationStrategy>
<executionStrategy>once-per-session</executionStrategy>
<parameters>
<parameter>
<name>project</name>
<type>org.apache.maven.project.MavenProject</type>
<required>true</required>
<editable>false</editable>
<description>The current MavenProject instance, for building a new MojoBinding instance.</description>
</parameter>
<parameter>
<name>groupId</name>
<type>java.lang.String</type>
<required>true</required>
<editable>true</editable>
<description>The plugin's groupId.</description>
</parameter>
<parameter>
<name>artifactId</name>
<type>java.lang.String</type>
<required>true</required>
<editable>true</editable>
<description>The plugin's artifactId.</description>
</parameter>
<parameter>
<name>version</name>
<type>java.lang.String</type>
<required>false</required>
<editable>true</editable>
<description>The plugin's version.</description>
</parameter>
<parameter>
<name>gaol</name>
<type>java.lang.String</type>
<required>true</required>
<editable>true</editable>
<description>The mojo's goal that we're looking for, as an extra validation step.</description>
</parameter>
</parameters>
<configuration>
<project implementation="org.apache.maven.project.MavenProject" default-value="${project}"/>
<groupId implementation="java.lang.String">${groupId}</groupId>
<artifactId implementation="java.lang.String">${artifactId}</artifactId>
<version implementation="java.lang.String">${version}</version>
<goal implementation="java.lang.String">${goal}</goal>
</configuration>
<requirements>
<requirement>
<role>org.apache.maven.plugin.loader.PluginLoader</role>
<field-name>pluginLoader</field-name>
</requirement>
<requirement>
<role>org.apache.maven.lifecycle.binding.MojoBindingFactory</role>
<field-name>bindingFactory</field-name>
</requirement>
</requirements>
</mojo>
</mojos>
</plugin>

View File

@ -266,9 +266,6 @@ under the License.
<requirement>
<role>org.apache.maven.context.BuildContextManager</role>
</requirement>
<requirement>
<role>org.apache.maven.lifecycle.binding.LifecycleBindingManager</role>
</requirement>
<requirement>
<role>org.apache.maven.plugin.loader.PluginLoader</role>
</requirement>

View File

@ -4,7 +4,6 @@ import org.apache.maven.lifecycle.LifecycleLoaderException;
import org.apache.maven.lifecycle.LifecycleSpecificationException;
import org.apache.maven.lifecycle.model.LifecycleBindings;
import org.apache.maven.lifecycle.model.MojoBinding;
import org.apache.maven.lifecycle.plan.LifecyclePlannerException;
import org.apache.maven.model.Build;
import org.apache.maven.model.Model;
import org.apache.maven.model.Plugin;
@ -14,24 +13,21 @@ import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.PlexusTestCase;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
public class DefaultLifecycleBindingManagerTest
extends PlexusTestCase
public class DefaultLifecycleBindingManagerTest extends PlexusTestCase
{
private LifecycleBindingManager mgr;
public void setUp()
throws Exception
public void setUp() throws Exception
{
super.setUp();
this.mgr = (LifecycleBindingManager) lookup( LifecycleBindingManager.ROLE, "default" );
mgr = (LifecycleBindingManager) lookup( LifecycleBindingManager.ROLE, "default" );
}
public void testLookup()
@ -92,7 +88,7 @@ public class DefaultLifecycleBindingManagerTest
Build build = new Build();
model.setBuild( build );
PluginManagement plugMgmt = new PluginManagement();
build.setPluginManagement( plugMgmt );
@ -182,7 +178,7 @@ public class DefaultLifecycleBindingManagerTest
assertEquals( "other-value", config.getChild( "test2" ).getValue() );
}
private Object createConfiguration( Properties configProperties )
private Object createConfiguration( final Properties configProperties )
{
Xpp3Dom config = new Xpp3Dom( "configuration" );
for ( Iterator it = configProperties.keySet().iterator(); it.hasNext(); )
@ -199,164 +195,4 @@ public class DefaultLifecycleBindingManagerTest
return config;
}
public void testAssembleMojoBindingList_ReturnBindingsUpToStopPhaseForSinglePhaseTaskList()
throws LifecycleSpecificationException, LifecyclePlannerException, LifecycleLoaderException
{
LifecycleBindings bindings = new LifecycleBindings();
bindings.getCleanBinding().getPreClean().addBinding( newMojoBinding( "goal", "artifact", "pre-clean" ) );
bindings.getCleanBinding().getClean().addBinding( newMojoBinding( "goal", "artifact", "clean" ) );
bindings.getCleanBinding().getPostClean().addBinding( newMojoBinding( "goal", "artifact", "post-clean" ) );
List result = mgr.assembleMojoBindingList( Collections.singletonList( "clean" ), bindings, new MavenProject( new Model() ) );
assertEquals( 2, result.size() );
MojoBinding binding = (MojoBinding) result.get( 0 );
assertEquals( "goal", binding.getGroupId() );
assertEquals( "artifact", binding.getArtifactId() );
assertEquals( "pre-clean", binding.getGoal() );
binding = (MojoBinding) result.get( 1 );
assertEquals( "goal", binding.getGroupId() );
assertEquals( "artifact", binding.getArtifactId() );
assertEquals( "clean", binding.getGoal() );
}
public void testAssembleMojoBindingList_CombinePreviousBindingsWhenSubsetOfNextBindingsForTwoPhaseTaskList()
throws LifecycleSpecificationException, LifecyclePlannerException, LifecycleLoaderException
{
LifecycleBindings bindings = new LifecycleBindings();
bindings.getCleanBinding().getPreClean().addBinding( newMojoBinding( "goal", "artifact", "pre-clean" ) );
bindings.getCleanBinding().getClean().addBinding( newMojoBinding( "goal", "artifact", "clean" ) );
bindings.getCleanBinding().getClean().addBinding( newMojoBinding( "goal", "artifact", "post-clean" ) );
List tasks = new ArrayList( 2 );
tasks.add( "clean" );
tasks.add( "post-clean" );
List result = mgr.assembleMojoBindingList( tasks, bindings, new MavenProject( new Model() ) );
assertEquals( 3, result.size() );
MojoBinding binding = (MojoBinding) result.get( 0 );
assertEquals( "goal", binding.getGroupId() );
assertEquals( "artifact", binding.getArtifactId() );
assertEquals( "pre-clean", binding.getGoal() );
binding = (MojoBinding) result.get( 1 );
assertEquals( "goal", binding.getGroupId() );
assertEquals( "artifact", binding.getArtifactId() );
assertEquals( "clean", binding.getGoal() );
binding = (MojoBinding) result.get( 2 );
assertEquals( "goal", binding.getGroupId() );
assertEquals( "artifact", binding.getArtifactId() );
assertEquals( "post-clean", binding.getGoal() );
}
public void testAssembleMojoBindingList_IgnoreSuccessiveBindingsWhenSameAsPreviousOnesForTwoPhaseTaskList()
throws LifecycleSpecificationException, LifecyclePlannerException, LifecycleLoaderException
{
LifecycleBindings bindings = new LifecycleBindings();
bindings.getCleanBinding().getPreClean().addBinding( newMojoBinding( "goal", "artifact", "pre-clean" ) );
bindings.getCleanBinding().getClean().addBinding( newMojoBinding( "goal", "artifact", "clean" ) );
List tasks = new ArrayList( 2 );
tasks.add( "clean" );
tasks.add( "post-clean" );
List result = mgr.assembleMojoBindingList( tasks, bindings, new MavenProject( new Model() ) );
assertEquals( 2, result.size() );
MojoBinding binding = (MojoBinding) result.get( 0 );
assertEquals( "goal", binding.getGroupId() );
assertEquals( "artifact", binding.getArtifactId() );
assertEquals( "pre-clean", binding.getGoal() );
binding = (MojoBinding) result.get( 1 );
assertEquals( "goal", binding.getGroupId() );
assertEquals( "artifact", binding.getArtifactId() );
assertEquals( "clean", binding.getGoal() );
}
public void testAssembleMojoBindingList_ReturnBindingsUpToStopPhasesForTwoPhaseTaskList()
throws LifecycleSpecificationException, LifecyclePlannerException, LifecycleLoaderException
{
LifecycleBindings bindings = new LifecycleBindings();
bindings.getCleanBinding().getPreClean().addBinding( newMojoBinding( "goal", "artifact", "pre-clean" ) );
bindings.getCleanBinding().getClean().addBinding( newMojoBinding( "goal", "artifact", "clean" ) );
bindings.getCleanBinding().getPostClean().addBinding( newMojoBinding( "goal", "artifact", "post-clean" ) );
bindings.getBuildBinding().getInitialize().addBinding( newMojoBinding( "goal", "artifact", "initialize" ) );
bindings.getBuildBinding().getCompile().addBinding( newMojoBinding( "goal", "artifact", "compile" ) );
bindings.getBuildBinding().getCreatePackage().addBinding( newMojoBinding( "goal", "artifact", "package" ) );
List tasks = new ArrayList( 2 );
tasks.add( "clean" );
tasks.add( "compile" );
List result = mgr.assembleMojoBindingList( tasks, bindings, new MavenProject( new Model() ) );
assertEquals( 4, result.size() );
MojoBinding binding = (MojoBinding) result.get( 0 );
assertEquals( "goal", binding.getGroupId() );
assertEquals( "artifact", binding.getArtifactId() );
assertEquals( "pre-clean", binding.getGoal() );
binding = (MojoBinding) result.get( 1 );
assertEquals( "goal", binding.getGroupId() );
assertEquals( "artifact", binding.getArtifactId() );
assertEquals( "clean", binding.getGoal() );
binding = (MojoBinding) result.get( 2 );
assertEquals( "goal", binding.getGroupId() );
assertEquals( "artifact", binding.getArtifactId() );
assertEquals( "initialize", binding.getGoal() );
binding = (MojoBinding) result.get( 3 );
assertEquals( "goal", binding.getGroupId() );
assertEquals( "artifact", binding.getArtifactId() );
assertEquals( "compile", binding.getGoal() );
}
public void testAssembleMojoBindingList_ThrowErrorForInvalidPhaseNameAsSingletonTaskList()
throws LifecyclePlannerException, LifecycleLoaderException
{
try
{
mgr.assembleMojoBindingList( Collections.singletonList( "dud" ), new LifecycleBindings(),
new MavenProject( new Model() ) );
fail( "Should fail with LifecycleSpecificationException due to invalid phase/direct mojo reference." );
}
catch ( LifecycleSpecificationException e )
{
// expected.
}
}
private MojoBinding newMojoBinding( String groupId, String artifactId, String goal )
{
MojoBinding binding = new MojoBinding();
binding.setGroupId( groupId );
binding.setArtifactId( artifactId );
binding.setGoal( goal );
return binding;
}
}

View File

@ -0,0 +1,98 @@
package org.apache.maven.lifecycle.plan;
import org.apache.maven.lifecycle.LifecycleLoaderException;
import org.apache.maven.lifecycle.LifecycleSpecificationException;
import org.apache.maven.lifecycle.MojoBindingUtils;
import org.apache.maven.lifecycle.model.BuildBinding;
import org.apache.maven.lifecycle.model.LifecycleBindings;
import org.apache.maven.lifecycle.model.MojoBinding;
import org.apache.maven.lifecycle.statemgmt.StateManagementUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Stack;
import junit.framework.TestCase;
public class BuildPlanTest
extends TestCase
{
public void testRender_OneDirectInvocationWithForkedPhase_NoLifecycleOverlay()
throws LifecycleSpecificationException, LifecycleLoaderException
{
List check = new ArrayList();
check.add( StateManagementUtils.createStartForkedExecutionMojoBinding() );
MojoBinding mb = new MojoBinding();
mb.setGroupId( "test" );
mb.setArtifactId( "test-plugin" );
mb.setVersion( "1" );
mb.setGoal( "validate" );
check.add( mb );
BuildBinding binding = new BuildBinding();
binding.getValidate().addBinding( mb );
mb = new MojoBinding();
mb.setGroupId( "test" );
mb.setArtifactId( "test-plugin" );
mb.setVersion( "1" );
mb.setGoal( "generate-sources" );
check.add( mb );
check.add( StateManagementUtils.createClearForkedExecutionMojoBinding() );
binding.getGenerateSources().addBinding( mb );
LifecycleBindings bindings = new LifecycleBindings();
bindings.setBuildBinding( binding );
List tasks = Collections.singletonList( "eclipse:eclipse" );
MojoBinding eclipseBinding = new MojoBinding();
eclipseBinding.setGroupId( "org.apache.maven.plugins" );
eclipseBinding.setArtifactId( "maven-eclipse-plugin" );
eclipseBinding.setVersion( "2.3" );
eclipseBinding.setGoal( "eclipse" );
check.add( eclipseBinding );
check.add( StateManagementUtils.createEndForkedExecutionMojoBinding() );
BuildPlan plan = new BuildPlan( new LifecycleBindings(), tasks );
plan.addDirectInvocationBinding( "eclipse:eclipse", eclipseBinding );
plan.addForkedExecution( eclipseBinding, new BuildPlan( bindings,
Collections.singletonList( "generate-sources" ) ) );
List executionPlan = plan.renderExecutionPlan( new Stack() );
assertBindings( check, executionPlan );
}
private void assertBindings( final List check, final List executionPlan )
{
assertNotNull( executionPlan );
System.out.println( "Expected execution plan:\n" + String.valueOf( check ).replace( ',', '\n' ) );
System.out.println( "\nActual execution plan:\n" + String.valueOf( executionPlan ).replace( ',', '\n' ) );
assertEquals( "Execution plan does not contain the expected number of mojo bindings.", check.size(),
executionPlan.size() );
for ( int i = 0; i < check.size(); i++ )
{
MojoBinding checkBinding = (MojoBinding) check.get( i );
MojoBinding realBinding = (MojoBinding) executionPlan.get( i );
assertEquals( "Expected mojo binding does not match execution plan.",
MojoBindingUtils.createMojoBindingKey( checkBinding, true ),
MojoBindingUtils.createMojoBindingKey( realBinding, true ) );
}
}
}

View File

@ -1,197 +0,0 @@
package org.apache.maven.lifecycle.plan;
import org.apache.maven.lifecycle.model.LifecycleBindings;
import org.apache.maven.lifecycle.model.MojoBinding;
import org.apache.maven.lifecycle.statemgmt.StateManagementUtils;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import junit.framework.TestCase;
public class ForkPlanModifierTest
extends TestCase
{
public void testModifyBindings_AddTwoMojosAheadOfCompileMojo()
throws LifecyclePlannerException
{
MojoBinding mojo = newMojo( "org.apache.maven.plugins", "maven-compiler-plugin", "compile" );
List additions = new ArrayList();
additions.add( newMojo( "group", "artifact", "clean" ) );
additions.add( newMojo( "group", "artifact", "compile" ) );
LifecycleBindings target = new LifecycleBindings();
assertEquals( 0, target.getBuildBinding().getCompile().getBindings().size() );
target.getBuildBinding().getCompile().addBinding( mojo );
assertEquals( 1, target.getBuildBinding().getCompile().getBindings().size() );
target = new ForkPlanModifier( mojo, additions ).modifyBindings( target );
assertEquals( 6, target.getBuildBinding().getCompile().getBindings().size() );
Iterator it = target.getBuildBinding().getCompile().getBindings().iterator();
assertMojo( StateManagementUtils.GROUP_ID, StateManagementUtils.ARTIFACT_ID,
StateManagementUtils.START_FORKED_EXECUTION_GOAL,
(MojoBinding) it.next() );
assertMojo( "group", "artifact", "clean", (MojoBinding) it.next() );
assertMojo( "group", "artifact", "compile", (MojoBinding) it.next() );
assertMojo( StateManagementUtils.GROUP_ID, StateManagementUtils.ARTIFACT_ID,
StateManagementUtils.END_FORKED_EXECUTION_GOAL,
(MojoBinding) it.next() );
assertMojo( mojo.getGroupId(), mojo.getArtifactId(), mojo.getGoal(),
(MojoBinding) it.next() );
assertMojo( StateManagementUtils.GROUP_ID, StateManagementUtils.ARTIFACT_ID,
StateManagementUtils.CLEAR_FORKED_EXECUTION_GOAL, (MojoBinding) it.next() );
}
public void testModifyBindings_AddTwoMojosBetweenTwoExistingCompileMojos()
throws LifecyclePlannerException
{
MojoBinding mojo = newMojo( "org.apache.maven.plugins", "maven-compiler-plugin", "compile" );
MojoBinding mojo2 = newMojo( "org.apache.maven.plugins", "maven-compiler-plugin", "compile2" );
List additions = new ArrayList();
additions.add( newMojo( "group", "artifact", "clean" ) );
additions.add( newMojo( "group", "artifact", "compile" ) );
LifecycleBindings target = new LifecycleBindings();
assertEquals( 0, target.getBuildBinding().getCompile().getBindings().size() );
target.getBuildBinding().getCompile().addBinding( mojo );
target.getBuildBinding().getCompile().addBinding( mojo2 );
assertEquals( 2, target.getBuildBinding().getCompile().getBindings().size() );
target = new ForkPlanModifier( mojo2, additions ).modifyBindings( target );
assertEquals( 7, target.getBuildBinding().getCompile().getBindings().size() );
Iterator it = target.getBuildBinding().getCompile().getBindings().iterator();
assertMojo( mojo.getGroupId(), mojo.getArtifactId(), mojo.getGoal(),
(MojoBinding) it.next() );
assertMojo( StateManagementUtils.GROUP_ID, StateManagementUtils.ARTIFACT_ID,
StateManagementUtils.START_FORKED_EXECUTION_GOAL,
(MojoBinding) it.next() );
assertMojo( "group", "artifact", "clean", (MojoBinding) it.next() );
assertMojo( "group", "artifact", "compile", (MojoBinding) it.next() );
assertMojo( StateManagementUtils.GROUP_ID, StateManagementUtils.ARTIFACT_ID,
StateManagementUtils.END_FORKED_EXECUTION_GOAL,
(MojoBinding) it.next() );
assertMojo( mojo2.getGroupId(), mojo2.getArtifactId(), mojo2.getGoal(),
(MojoBinding) it.next() );
assertMojo( StateManagementUtils.GROUP_ID, StateManagementUtils.ARTIFACT_ID,
StateManagementUtils.CLEAR_FORKED_EXECUTION_GOAL, (MojoBinding) it.next() );
}
public void testModifyBindings_AddTwoNormalPlusTwoModifierModifiedMojosWithTwoExistingCompileMojos()
throws LifecyclePlannerException
{
MojoBinding mojo = newMojo( "org.apache.maven.plugins", "maven-compiler-plugin", "compile" );
MojoBinding mojo2 = newMojo( "org.apache.maven.plugins", "maven-compiler-plugin", "compile2" );
List modAdditions = new ArrayList();
modAdditions.add( newMojo( "group2", "artifact", "clean" ) );
modAdditions.add( newMojo( "group2", "artifact", "compile" ) );
MojoBinding mojo3 = newMojo( "group", "artifact", "clean" );
List additions = new ArrayList();
additions.add( mojo3 );
additions.add( newMojo( "group", "artifact", "compile" ) );
LifecycleBindings target = new LifecycleBindings();
assertEquals( 0, target.getBuildBinding().getCompile().getBindings().size() );
target.getBuildBinding().getCompile().addBinding( mojo );
target.getBuildBinding().getCompile().addBinding( mojo2 );
assertEquals( 2, target.getBuildBinding().getCompile().getBindings().size() );
BuildPlanModifier modder = new ForkPlanModifier( mojo, additions );
modder.addModifier( new ForkPlanModifier( mojo3, modAdditions ) );
target = modder.modifyBindings( target );
assertEquals( 12, target.getBuildBinding().getCompile().getBindings().size() );
Iterator it = target.getBuildBinding().getCompile().getBindings().iterator();
assertMojo( StateManagementUtils.GROUP_ID, StateManagementUtils.ARTIFACT_ID,
StateManagementUtils.START_FORKED_EXECUTION_GOAL,
(MojoBinding) it.next() );
assertMojo( StateManagementUtils.GROUP_ID, StateManagementUtils.ARTIFACT_ID,
StateManagementUtils.START_FORKED_EXECUTION_GOAL,
(MojoBinding) it.next() );
assertMojo( "group2", "artifact", "clean", (MojoBinding) it.next() );
assertMojo( "group2", "artifact", "compile", (MojoBinding) it.next() );
assertMojo( StateManagementUtils.GROUP_ID, StateManagementUtils.ARTIFACT_ID,
StateManagementUtils.END_FORKED_EXECUTION_GOAL,
(MojoBinding) it.next() );
assertMojo( mojo3.getGroupId(), mojo3.getArtifactId(), mojo3.getGoal(),
(MojoBinding) it.next() );
assertMojo( StateManagementUtils.GROUP_ID, StateManagementUtils.ARTIFACT_ID,
StateManagementUtils.CLEAR_FORKED_EXECUTION_GOAL, (MojoBinding) it.next() );
assertMojo( "group", "artifact", "compile", (MojoBinding) it.next() );
assertMojo( StateManagementUtils.GROUP_ID, StateManagementUtils.ARTIFACT_ID,
StateManagementUtils.END_FORKED_EXECUTION_GOAL,
(MojoBinding) it.next() );
assertMojo( mojo.getGroupId(), mojo.getArtifactId(), mojo.getGoal(),
(MojoBinding) it.next() );
assertMojo( StateManagementUtils.GROUP_ID, StateManagementUtils.ARTIFACT_ID,
StateManagementUtils.CLEAR_FORKED_EXECUTION_GOAL, (MojoBinding) it.next() );
assertMojo( mojo2.getGroupId(), mojo2.getArtifactId(), mojo2.getGoal(),
(MojoBinding) it.next() );
}
private void assertMojo( String groupId, String artifactId, String goal, MojoBinding binding )
{
assertEquals( groupId, binding.getGroupId() );
assertEquals( artifactId, binding.getArtifactId() );
assertEquals( goal, binding.getGoal() );
}
private MojoBinding newMojo( String groupId, String artifactId, String goal )
{
MojoBinding binding = new MojoBinding();
binding.setGroupId( groupId );
binding.setArtifactId( artifactId );
binding.setGoal( goal );
return binding;
}
}

View File

@ -1,122 +0,0 @@
package org.apache.maven.lifecycle.plan;
import org.apache.maven.lifecycle.LifecycleLoaderException;
import org.apache.maven.lifecycle.LifecycleSpecificationException;
import org.apache.maven.lifecycle.binding.LifecycleBindingManager;
import org.apache.maven.lifecycle.model.LifecycleBindings;
import org.apache.maven.lifecycle.model.MojoBinding;
import org.apache.maven.lifecycle.statemgmt.StateManagementUtils;
import org.codehaus.plexus.PlexusTestCase;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
public class LifecycleBuildPlanTest
extends PlexusTestCase
{
private LifecycleBindingManager bindingManager;
public void setUp()
throws Exception
{
super.setUp();
bindingManager = (LifecycleBindingManager) lookup( LifecycleBindingManager.ROLE, "default" );
}
public void testSingleTask_TwoMojoBindings()
throws LifecycleSpecificationException, LifecyclePlannerException, LifecycleLoaderException
{
LifecycleBindings bindings = new LifecycleBindings();
bindings.getCleanBinding().getPreClean().addBinding( newMojo( "group", "artifact", "pre-clean" ) );
bindings.getCleanBinding().getClean().addBinding( newMojo( "group", "artifact", "clean" ) );
List plan = new LifecycleBuildPlan( Collections.singletonList( "clean" ), bindings ).getPlanMojoBindings( null,
bindingManager );
assertEquals( 2, plan.size() );
assertMojo( "group", "artifact", "pre-clean", (MojoBinding) plan.get( 0 ) );
assertMojo( "group", "artifact", "clean", (MojoBinding) plan.get( 1 ) );
}
public void testTwoAdditiveTasksInOrder_ThreeMojoBindings_NoDupes()
throws LifecycleSpecificationException, LifecyclePlannerException, LifecycleLoaderException
{
LifecycleBindings bindings = new LifecycleBindings();
bindings.getCleanBinding().getPreClean().addBinding( newMojo( "group", "artifact", "pre-clean" ) );
bindings.getCleanBinding().getClean().addBinding( newMojo( "group", "artifact", "clean" ) );
bindings.getCleanBinding().getClean().addBinding( newMojo( "group", "artifact", "post-clean" ) );
List tasks = new ArrayList();
tasks.add( "clean" );
tasks.add( "post-clean" );
List plan = new LifecycleBuildPlan( tasks, bindings ).getPlanMojoBindings( null, bindingManager );
assertEquals( 3, plan.size() );
assertMojo( "group", "artifact", "pre-clean", (MojoBinding) plan.get( 0 ) );
assertMojo( "group", "artifact", "clean", (MojoBinding) plan.get( 1 ) );
assertMojo( "group", "artifact", "post-clean", (MojoBinding) plan.get( 2 ) );
}
public void testTwoAdditiveTasksInOrder_TwoMojoBindings_OneMojoModifierInsertedBetween_NoDupes()
throws LifecycleSpecificationException, LifecyclePlannerException, LifecycleLoaderException
{
MojoBinding clean = newMojo( "group", "artifact", "clean" );
List mods = Collections.singletonList( newMojo( "group", "artifact", "pre-clean" ) );
BuildPlanModifier modder = new ForkPlanModifier( clean, mods );
LifecycleBindings bindings = new LifecycleBindings();
bindings.getCleanBinding().getPreClean().addBinding( clean );
bindings.getCleanBinding().getClean().addBinding( newMojo( "group", "artifact", "post-clean" ) );
List tasks = new ArrayList();
tasks.add( "clean" );
tasks.add( "post-clean" );
BuildPlan lifecyclePlan = new LifecycleBuildPlan( tasks, bindings );
lifecyclePlan.addModifier( modder );
List plan = lifecyclePlan.getPlanMojoBindings( null, bindingManager );
assertEquals( 6, plan.size() );
Iterator it = plan.iterator();
assertMojo( StateManagementUtils.GROUP_ID, StateManagementUtils.ARTIFACT_ID,
StateManagementUtils.START_FORKED_EXECUTION_GOAL, (MojoBinding) it.next() );
assertMojo( "group", "artifact", "pre-clean", (MojoBinding) it.next() );
assertMojo( StateManagementUtils.GROUP_ID, StateManagementUtils.ARTIFACT_ID,
StateManagementUtils.END_FORKED_EXECUTION_GOAL, (MojoBinding) it.next() );
assertMojo( "group", "artifact", "clean", (MojoBinding) it.next() );
assertMojo( StateManagementUtils.GROUP_ID, StateManagementUtils.ARTIFACT_ID,
StateManagementUtils.CLEAR_FORKED_EXECUTION_GOAL, (MojoBinding) it.next() );
assertMojo( "group", "artifact", "post-clean", (MojoBinding) it.next() );
}
private void assertMojo( String groupId, String artifactId, String goal, MojoBinding binding )
{
assertEquals( groupId, binding.getGroupId() );
assertEquals( artifactId, binding.getArtifactId() );
assertEquals( goal, binding.getGoal() );
}
private MojoBinding newMojo( String groupId, String artifactId, String goal )
{
MojoBinding binding = new MojoBinding();
binding.setGroupId( groupId );
binding.setArtifactId( artifactId );
binding.setGoal( goal );
return binding;
}
}

View File

@ -1,146 +0,0 @@
package org.apache.maven.lifecycle.plan;
import org.apache.maven.lifecycle.model.LifecycleBindings;
import org.apache.maven.lifecycle.model.MojoBinding;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import junit.framework.TestCase;
public class ReportingPlanModifierTest
extends TestCase
{
public void testModifyBindings_AddTwoMojosAheadOfCompileMojo()
throws LifecyclePlannerException
{
MojoBinding mojo = newMojo( "org.apache.maven.plugins", "maven-compiler-plugin", "compile" );
List additions = new ArrayList();
additions.add( newMojo( "group", "artifact", "clean" ) );
additions.add( newMojo( "group", "artifact", "compile" ) );
LifecycleBindings target = new LifecycleBindings();
assertEquals( 0, target.getBuildBinding().getCompile().getBindings().size() );
target.getBuildBinding().getCompile().addBinding( mojo );
assertEquals( 1, target.getBuildBinding().getCompile().getBindings().size() );
target = new ReportingPlanModifier( mojo, additions ).modifyBindings( target );
assertEquals( 3, target.getBuildBinding().getCompile().getBindings().size() );
Iterator it = target.getBuildBinding().getCompile().getBindings().iterator();
assertMojo( "group", "artifact", "clean", (MojoBinding) it.next() );
assertMojo( "group", "artifact", "compile", (MojoBinding) it.next() );
assertMojo( mojo.getGroupId(), mojo.getArtifactId(), mojo.getGoal(), (MojoBinding) it.next() );
}
public void testModifyBindings_AddTwoMojosBetweenTwoExistingCompileMojos()
throws LifecyclePlannerException
{
MojoBinding mojo = newMojo( "org.apache.maven.plugins", "maven-compiler-plugin", "compile" );
MojoBinding mojo2 = newMojo( "org.apache.maven.plugins", "maven-compiler-plugin", "compile2" );
List additions = new ArrayList();
additions.add( newMojo( "group", "artifact", "clean" ) );
additions.add( newMojo( "group", "artifact", "compile" ) );
LifecycleBindings target = new LifecycleBindings();
assertEquals( 0, target.getBuildBinding().getCompile().getBindings().size() );
target.getBuildBinding().getCompile().addBinding( mojo );
target.getBuildBinding().getCompile().addBinding( mojo2 );
assertEquals( 2, target.getBuildBinding().getCompile().getBindings().size() );
target = new ReportingPlanModifier( mojo2, additions ).modifyBindings( target );
assertEquals( 4, target.getBuildBinding().getCompile().getBindings().size() );
Iterator it = target.getBuildBinding().getCompile().getBindings().iterator();
assertMojo( mojo.getGroupId(), mojo.getArtifactId(), mojo.getGoal(), (MojoBinding) it.next() );
assertMojo( "group", "artifact", "clean", (MojoBinding) it.next() );
assertMojo( "group", "artifact", "compile", (MojoBinding) it.next() );
assertMojo( mojo2.getGroupId(), mojo2.getArtifactId(), mojo2.getGoal(), (MojoBinding) it.next() );
}
public void testModifyBindings_AddTwoNormalPlusTwoModifierModifiedMojosWithTwoExistingCompileMojos()
throws LifecyclePlannerException
{
MojoBinding mojo = newMojo( "org.apache.maven.plugins", "maven-compiler-plugin", "compile" );
MojoBinding mojo2 = newMojo( "org.apache.maven.plugins", "maven-compiler-plugin", "compile2" );
List modAdditions = new ArrayList();
modAdditions.add( newMojo( "group2", "artifact", "clean" ) );
modAdditions.add( newMojo( "group2", "artifact", "compile" ) );
MojoBinding mojo3 = newMojo( "group", "artifact", "clean" );
List additions = new ArrayList();
additions.add( mojo3 );
additions.add( newMojo( "group", "artifact", "compile" ) );
LifecycleBindings target = new LifecycleBindings();
assertEquals( 0, target.getBuildBinding().getCompile().getBindings().size() );
target.getBuildBinding().getCompile().addBinding( mojo );
target.getBuildBinding().getCompile().addBinding( mojo2 );
assertEquals( 2, target.getBuildBinding().getCompile().getBindings().size() );
BuildPlanModifier modder = new ReportingPlanModifier( mojo, additions );
modder.addModifier( new ReportingPlanModifier( mojo3, modAdditions ) );
target = modder.modifyBindings( target );
assertEquals( 6, target.getBuildBinding().getCompile().getBindings().size() );
Iterator it = target.getBuildBinding().getCompile().getBindings().iterator();
assertMojo( "group2", "artifact", "clean", (MojoBinding) it.next() );
assertMojo( "group2", "artifact", "compile", (MojoBinding) it.next() );
assertMojo( mojo3.getGroupId(), mojo3.getArtifactId(), mojo3.getGoal(), (MojoBinding) it.next() );
assertMojo( "group", "artifact", "compile", (MojoBinding) it.next() );
assertMojo( mojo.getGroupId(), mojo.getArtifactId(), mojo.getGoal(), (MojoBinding) it.next() );
assertMojo( mojo2.getGroupId(), mojo2.getArtifactId(), mojo2.getGoal(), (MojoBinding) it.next() );
}
private void assertMojo( String groupId, String artifactId, String goal, MojoBinding binding )
{
assertEquals( groupId, binding.getGroupId() );
assertEquals( artifactId, binding.getArtifactId() );
assertEquals( goal, binding.getGoal() );
}
private MojoBinding newMojo( String groupId, String artifactId, String goal )
{
MojoBinding binding = new MojoBinding();
binding.setGroupId( groupId );
binding.setArtifactId( artifactId );
binding.setGoal( goal );
return binding;
}
}

View File

@ -42,7 +42,7 @@ under the License.
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.1</version>
<version>2.2-beta-1</version>
<configuration>
<descriptor>src/main/assembly/bin.xml</descriptor>
<finalName>maven-${version}</finalName>
@ -51,7 +51,7 @@ under the License.
<execution>
<phase>install</phase>
<goals>
<goal>attached</goal>
<goal>single</goal>
</goals>
</execution>
</executions>

View File

@ -22,7 +22,7 @@ public class LifecycleUtils
{
}
public static void setOrigin( LifecycleBindings bindings, String origin )
public static void setOrigin( final LifecycleBindings bindings, final String origin )
{
for ( Iterator bindingIt = bindings.getBindingList().iterator(); bindingIt.hasNext(); )
{
@ -52,7 +52,7 @@ public class LifecycleUtils
}
}
public static List getMojoBindingListForLifecycle( String stopPhase, LifecycleBindings bindings )
public static List getMojoBindingListForLifecycle( final String stopPhase, final LifecycleBindings bindings )
throws NoSuchPhaseException
{
LifecycleBinding binding = findLifecycleBindingForPhase( stopPhase, bindings );
@ -65,7 +65,7 @@ public class LifecycleUtils
return getMojoBindingListForLifecycle( stopPhase, binding );
}
public static List getMojoBindingListForLifecycle( String stopPhase, LifecycleBinding lifecycle )
public static List getMojoBindingListForLifecycle( final String stopPhase, final LifecycleBinding lifecycle )
throws NoSuchPhaseException
{
List phaseNames = lifecycle.getPhaseNamesInOrder();
@ -85,7 +85,7 @@ public class LifecycleUtils
Phase phase = (Phase) phases.get( i );
List phaseBindings = phase.getBindings();
if ( phaseBindings != null && !phaseBindings.isEmpty() )
if ( ( phaseBindings != null ) && !phaseBindings.isEmpty() )
{
bindings.addAll( phaseBindings );
}
@ -97,7 +97,8 @@ public class LifecycleUtils
/**
* @return null if the phase is not contained in any of the lifecycles.
*/
public static LifecycleBinding findLifecycleBindingForPhase( String phaseName, LifecycleBindings lifecycles )
public static LifecycleBinding findLifecycleBindingForPhase( final String phaseName,
final LifecycleBindings lifecycles )
{
List lifecyclesAvailable = lifecycles.getBindingList();
@ -114,8 +115,8 @@ public class LifecycleUtils
return null;
}
public static void removeMojoBinding( String phaseName, MojoBinding mojoBinding, LifecycleBinding lifecycleBinding,
boolean considerExecutionId )
public static void removeMojoBinding( final String phaseName, final MojoBinding mojoBinding,
final LifecycleBinding lifecycleBinding, final boolean considerExecutionId )
throws NoSuchPhaseException
{
List phaseNames = lifecycleBinding.getPhaseNamesInOrder();
@ -125,7 +126,7 @@ public class LifecycleUtils
if ( idx < 0 )
{
throw new NoSuchPhaseException( phaseName, "Phase: " + phaseName + " not found in lifecycle: "
+ lifecycleBinding.getId() );
+ lifecycleBinding.getId() );
}
List phases = lifecycleBinding.getPhasesInOrder();
@ -136,13 +137,13 @@ public class LifecycleUtils
{
List mojoBindings = phase.getBindings();
String targetKey = createMojoBindingKey( mojoBinding, considerExecutionId );
String targetKey = MojoBindingUtils.createMojoBindingKey( mojoBinding, considerExecutionId );
for ( Iterator it = mojoBindings.iterator(); it.hasNext(); )
{
MojoBinding candidate = (MojoBinding) it.next();
String candidateKey = createMojoBindingKey( candidate, considerExecutionId );
String candidateKey = MojoBindingUtils.createMojoBindingKey( candidate, considerExecutionId );
if ( candidateKey.equals( targetKey ) )
{
it.remove();
@ -153,8 +154,8 @@ public class LifecycleUtils
}
}
public static void addMojoBinding( String phaseName, MojoBinding mojoBinding, LifecycleBinding lifecycleBinding )
throws NoSuchPhaseException
public static void addMojoBinding( final String phaseName, final MojoBinding mojoBinding,
final LifecycleBinding lifecycleBinding ) throws NoSuchPhaseException
{
List phaseNames = lifecycleBinding.getPhaseNamesInOrder();
@ -163,7 +164,7 @@ public class LifecycleUtils
if ( idx < 0 )
{
throw new NoSuchPhaseException( phaseName, "Phase: " + phaseName + " not found in lifecycle: "
+ lifecycleBinding.getId() );
+ lifecycleBinding.getId() );
}
List phases = lifecycleBinding.getPhasesInOrder();
@ -172,7 +173,7 @@ public class LifecycleUtils
phase.addBinding( mojoBinding );
}
public static void addMojoBinding( String phaseName, MojoBinding mojo, LifecycleBindings bindings )
public static void addMojoBinding( final String phaseName, final MojoBinding mojo, final LifecycleBindings bindings )
throws LifecycleSpecificationException
{
LifecycleBinding binding = findLifecycleBindingForPhase( phaseName, bindings );
@ -185,21 +186,25 @@ public class LifecycleUtils
addMojoBinding( phaseName, mojo, binding );
}
public static LifecycleBindings mergeBindings( LifecycleBindings existingBindings, LifecycleBindings newBindings,
LifecycleBindings defaultBindings, boolean mergeConfigIfExecutionIdMatches )
public static LifecycleBindings mergeBindings( final LifecycleBindings existingBindings,
final LifecycleBindings newBindings,
final LifecycleBindings defaultBindings,
final boolean mergeConfigIfExecutionIdMatches )
{
return mergeBindings( existingBindings, newBindings, defaultBindings, mergeConfigIfExecutionIdMatches, false );
}
public static LifecycleBindings mergeBindings( LifecycleBindings existingBindings, LifecycleBindings newBindings,
LifecycleBindings defaultBindings, boolean mergeConfigIfExecutionIdMatches,
boolean reverseConfigMergeDirection )
public static LifecycleBindings mergeBindings( final LifecycleBindings existingBindings,
final LifecycleBindings newBindings,
final LifecycleBindings defaultBindings,
final boolean mergeConfigIfExecutionIdMatches,
final boolean reverseConfigMergeDirection )
{
LifecycleBindings result = new LifecycleBindings();
result.setPackaging( newBindings.getPackaging() );
CleanBinding cb = (CleanBinding) cloneBinding( existingBindings.getCleanBinding() );
if ( defaultBindings != null && isNullOrEmpty( cb ) )
if ( ( defaultBindings != null ) && isNullOrEmpty( cb ) )
{
cb = (CleanBinding) cloneBinding( defaultBindings.getCleanBinding() );
}
@ -212,7 +217,7 @@ public class LifecycleUtils
result.setCleanBinding( cb );
BuildBinding bb = (BuildBinding) cloneBinding( existingBindings.getBuildBinding() );
if ( defaultBindings != null && isNullOrEmpty( bb ) )
if ( ( defaultBindings != null ) && isNullOrEmpty( bb ) )
{
bb = (BuildBinding) cloneBinding( defaultBindings.getBuildBinding() );
}
@ -225,7 +230,7 @@ public class LifecycleUtils
result.setBuildBinding( bb );
SiteBinding sb = (SiteBinding) cloneBinding( existingBindings.getSiteBinding() );
if ( defaultBindings != null && isNullOrEmpty( sb ) )
if ( ( defaultBindings != null ) && isNullOrEmpty( sb ) )
{
sb = (SiteBinding) cloneBinding( defaultBindings.getSiteBinding() );
}
@ -251,7 +256,7 @@ public class LifecycleUtils
Phase phase = (Phase) phases.get( i );
String name = (String) phaseNames.get( i );
if ( phase != null && phase.getBindings() != null && !phase.getBindings().isEmpty() )
if ( ( phase != null ) && ( phase.getBindings() != null ) && !phase.getBindings().isEmpty() )
{
for ( Iterator phaseIt = phase.getBindings().iterator(); phaseIt.hasNext(); )
{
@ -261,40 +266,46 @@ public class LifecycleUtils
if ( mergeConfigIfExecutionIdMatches )
{
MojoBinding matchingBinding = findMatchingMojoBinding( mojoBinding, existingBindings, true );
MojoBinding matchingBinding =
findMatchingMojoBinding( mojoBinding, existingBindings, true );
if ( matchingBinding != null )
{
Xpp3Dom existingConfig = new Xpp3Dom( (Xpp3Dom) matchingBinding.getConfiguration() );
Xpp3Dom configuration;
if ( reverseConfigMergeDirection )
{
configuration = Xpp3Dom.mergeXpp3Dom( existingConfig, (Xpp3Dom) mojoBinding.getConfiguration() );
configuration =
Xpp3Dom.mergeXpp3Dom( existingConfig,
(Xpp3Dom) mojoBinding.getConfiguration() );
}
else
{
configuration = Xpp3Dom.mergeXpp3Dom( (Xpp3Dom) mojoBinding.getConfiguration(), existingConfig );
configuration =
Xpp3Dom.mergeXpp3Dom( (Xpp3Dom) mojoBinding.getConfiguration(),
existingConfig );
}
mojoBinding.setConfiguration( configuration );
if ( mojoBinding.getOrigin() == null && matchingBinding.getOrigin() != null )
if ( ( mojoBinding.getOrigin() == null ) && ( matchingBinding.getOrigin() != null ) )
{
mojoBinding.setOrigin( matchingBinding.getOrigin() );
}
LifecycleBinding resultBinding = findLifecycleBindingForPhase( name, result );
try
{
removeMojoBinding( name, matchingBinding, resultBinding, true );
}
catch ( NoSuchPhaseException e )
{
IllegalStateException error = new IllegalStateException(
e.getMessage()
+ "\nSomething strange is going on. Merging should not encounter such inconsistencies." );
IllegalStateException error =
new IllegalStateException(
e.getMessage()
+ "\nSomething strange is going on. Merging should not encounter such inconsistencies." );
error.initCause( e );
@ -311,9 +322,9 @@ public class LifecycleUtils
{
// NOTE: this shouldn't happen as long as normal components are used
// to create/read these LifecycleBindings instances.
IllegalArgumentException error = new IllegalArgumentException(
"Project bindings are invalid. Reason: "
+ e.getMessage() );
IllegalArgumentException error =
new IllegalArgumentException( "Project bindings are invalid. Reason: "
+ e.getMessage() );
error.initCause( e );
@ -328,35 +339,36 @@ public class LifecycleUtils
return result;
}
private static boolean isNullOrEmpty( LifecycleBinding binding )
private static boolean isNullOrEmpty( final LifecycleBinding binding )
{
if ( binding == null )
{
return true;
}
for ( Iterator it = binding.getPhasesInOrder().iterator(); it.hasNext(); )
{
Phase phase = (Phase) it.next();
if ( !phase.getBindings().isEmpty() )
{
return false;
}
}
return true;
}
public static MojoBinding findMatchingMojoBinding( MojoBinding mojoBinding, LifecycleBindings inBindings,
boolean considerExecutionId )
public static MojoBinding findMatchingMojoBinding( final MojoBinding mojoBinding,
final LifecycleBindings inBindings,
final boolean considerExecutionId )
{
String key = createMojoBindingKey( mojoBinding, considerExecutionId );
String key = MojoBindingUtils.createMojoBindingKey( mojoBinding, considerExecutionId );
return (MojoBinding) mapMojoBindingsByKey( inBindings, considerExecutionId ).get( key );
}
private static Map mapMojoBindingsByKey( LifecycleBindings bindings, boolean considerExecutionId )
private static Map mapMojoBindingsByKey( final LifecycleBindings bindings, final boolean considerExecutionId )
{
Map byKey = new HashMap();
@ -376,7 +388,8 @@ public class LifecycleUtils
{
MojoBinding mojoBinding = (MojoBinding) mojoIt.next();
byKey.put( createMojoBindingKey( mojoBinding, considerExecutionId ), mojoBinding );
byKey.put( MojoBindingUtils.createMojoBindingKey( mojoBinding, considerExecutionId ),
mojoBinding );
}
}
}
@ -386,8 +399,8 @@ public class LifecycleUtils
return byKey;
}
public static void removeMojoBindings( List toRemove, LifecycleBindings bindings, boolean considerExecutionId )
throws NoSuchPhaseException
public static void removeMojoBindings( final List toRemove, final LifecycleBindings bindings,
final boolean considerExecutionId ) throws NoSuchPhaseException
{
if ( bindings.getCleanBinding() != null )
{
@ -405,8 +418,8 @@ public class LifecycleUtils
}
}
public static void removeMojoBindings( List toRemove, LifecycleBinding removeFrom, boolean considerExecutionId )
throws NoSuchPhaseException
public static void removeMojoBindings( final List toRemove, final LifecycleBinding removeFrom,
final boolean considerExecutionId ) throws NoSuchPhaseException
{
// remove where gid:aid:goal matches.
List targets = new ArrayList();
@ -414,7 +427,7 @@ public class LifecycleUtils
{
MojoBinding binding = (MojoBinding) it.next();
targets.add( createMojoBindingKey( binding, considerExecutionId ) );
targets.add( MojoBindingUtils.createMojoBindingKey( binding, considerExecutionId ) );
}
List phases = removeFrom.getPhasesInOrder();
@ -427,7 +440,7 @@ public class LifecycleUtils
for ( Iterator mojoIt = phaseBindings.iterator(); mojoIt.hasNext(); )
{
MojoBinding binding = (MojoBinding) mojoIt.next();
String key = createMojoBindingKey( binding, considerExecutionId );
String key = MojoBindingUtils.createMojoBindingKey( binding, considerExecutionId );
if ( targets.contains( key ) )
{
mojoIt.remove();
@ -438,19 +451,7 @@ public class LifecycleUtils
}
}
public static String createMojoBindingKey( MojoBinding mojoBinding, boolean considerExecutionId )
{
String key = mojoBinding.getGroupId() + ":" + mojoBinding.getArtifactId() + ":" + mojoBinding.getGoal();
if ( considerExecutionId )
{
key += ":" + mojoBinding.getExecutionId();
}
return key;
}
public static LifecycleBindings cloneBindings( LifecycleBindings bindings )
public static LifecycleBindings cloneBindings( final LifecycleBindings bindings )
{
LifecycleBindings result = new LifecycleBindings();
@ -472,7 +473,7 @@ public class LifecycleUtils
return result;
}
public static LifecycleBinding cloneBinding( LifecycleBinding binding )
public static LifecycleBinding cloneBinding( final LifecycleBinding binding )
{
if ( binding == null )
{
@ -495,7 +496,7 @@ public class LifecycleUtils
else
{
throw new IllegalArgumentException( "Unrecognized LifecycleBinding type: " + binding.getClass().getName()
+ "; cannot clone." );
+ "; cannot clone." );
}
List phases = binding.getPhasesInOrder();
@ -518,8 +519,10 @@ public class LifecycleUtils
}
catch ( NoSuchPhaseException e )
{
IllegalStateException error = new IllegalStateException( e.getMessage()
+ "\nSomething strange is going on. Cloning should not encounter such inconsistencies." );
IllegalStateException error =
new IllegalStateException(
e.getMessage()
+ "\nSomething strange is going on. Cloning should not encounter such inconsistencies." );
error.initCause( e );
@ -531,7 +534,7 @@ public class LifecycleUtils
return result;
}
public static MojoBinding cloneMojoBinding( MojoBinding binding )
public static MojoBinding cloneMojoBinding( final MojoBinding binding )
{
MojoBinding result = new MojoBinding();
@ -546,10 +549,11 @@ public class LifecycleUtils
return result;
}
public static Phase findPhaseForMojoBinding( MojoBinding mojoBinding, LifecycleBindings lifecycleBindings,
boolean considerExecutionId )
public static Phase findPhaseForMojoBinding( final MojoBinding mojoBinding,
final LifecycleBindings lifecycleBindings,
final boolean considerExecutionId )
{
String targetKey = createMojoBindingKey( mojoBinding, considerExecutionId );
String targetKey = MojoBindingUtils.createMojoBindingKey( mojoBinding, considerExecutionId );
for ( Iterator lifecycleIt = lifecycleBindings.getBindingList().iterator(); lifecycleIt.hasNext(); )
{
@ -562,7 +566,7 @@ public class LifecycleUtils
for ( Iterator mojoIt = phase.getBindings().iterator(); mojoIt.hasNext(); )
{
MojoBinding candidate = (MojoBinding) mojoIt.next();
String key = createMojoBindingKey( candidate, considerExecutionId );
String key = MojoBindingUtils.createMojoBindingKey( candidate, considerExecutionId );
if ( key.equals( targetKey ) )
{
return phase;
@ -574,15 +578,16 @@ public class LifecycleUtils
return null;
}
public static boolean isMojoBindingPresent( MojoBinding binding, List candidates, boolean considerExecutionId )
public static boolean isMojoBindingPresent( final MojoBinding binding, final List candidates,
final boolean considerExecutionId )
{
String key = createMojoBindingKey( binding, considerExecutionId );
String key = MojoBindingUtils.createMojoBindingKey( binding, considerExecutionId );
for ( Iterator it = candidates.iterator(); it.hasNext(); )
{
MojoBinding candidate = (MojoBinding) it.next();
String candidateKey = createMojoBindingKey( candidate, considerExecutionId );
String candidateKey = MojoBindingUtils.createMojoBindingKey( candidate, considerExecutionId );
if ( candidateKey.equals( key ) )
{
@ -593,79 +598,87 @@ public class LifecycleUtils
return false;
}
public static boolean isValidPhaseName( String phaseName )
public static boolean isValidPhaseName( final String phaseName )
{
LifecycleBindings test = new LifecycleBindings();
for ( Iterator it = test.getBindingList().iterator(); it.hasNext(); )
{
LifecycleBinding binding = (LifecycleBinding) it.next();
if ( binding.getPhaseNamesInOrder().contains( phaseName ) )
{
return true;
}
}
return false;
}
public static List getValidPhaseNames()
{
List phaseNames = new ArrayList();
LifecycleBindings bindings = new LifecycleBindings();
for ( Iterator bindingIt = bindings.getBindingList().iterator(); bindingIt.hasNext(); )
{
LifecycleBinding binding = (LifecycleBinding) bindingIt.next();
for ( Iterator phaseNameIt = binding.getPhaseNamesInOrder().iterator(); phaseNameIt.hasNext(); )
{
phaseNames.add( phaseNameIt.next() );
}
}
return phaseNames;
}
public static List getValidBuildPhaseNames()
{
List phaseNames = new ArrayList();
LifecycleBinding binding = new BuildBinding();
for ( Iterator phaseNameIt = binding.getPhaseNamesInOrder().iterator(); phaseNameIt.hasNext(); )
{
phaseNames.add( phaseNameIt.next() );
}
return phaseNames;
}
public static List getValidCleanPhaseNames()
{
List phaseNames = new ArrayList();
LifecycleBinding binding = new CleanBinding();
for ( Iterator phaseNameIt = binding.getPhaseNamesInOrder().iterator(); phaseNameIt.hasNext(); )
{
phaseNames.add( phaseNameIt.next() );
}
return phaseNames;
}
public static List getValidSitePhaseNames()
{
List phaseNames = new ArrayList();
LifecycleBinding binding = new SiteBinding();
for ( Iterator phaseNameIt = binding.getPhaseNamesInOrder().iterator(); phaseNameIt.hasNext(); )
{
phaseNames.add( phaseNameIt.next() );
}
return phaseNames;
}
/**
* @deprecated Use {@link MojoBindingUtils#createMojoBindingKey(MojoBinding, boolean)} instead.
*/
public static String createMojoBindingKey( final MojoBinding mojoBinding, final boolean considerExecutionId )
{
return MojoBindingUtils.createMojoBindingKey( mojoBinding, considerExecutionId );
}
}

View File

@ -9,10 +9,35 @@ public final class MojoBindingUtils
{
}
public static String toString( MojoBinding mojoBinding )
public static String toString( final MojoBinding mojoBinding )
{
return mojoBinding.getGroupId() + ":" + mojoBinding.getArtifactId() + ":"
+ ( mojoBinding.getVersion() == null ? "" : mojoBinding.getVersion() + ":" ) + mojoBinding.getGoal();
+ ( mojoBinding.getVersion() == null ? "" : mojoBinding.getVersion() + ":" )
+ mojoBinding.getGoal();
}
public static String createMojoBindingKey( final MojoBinding mojoBinding, final boolean considerExecutionId )
{
String key = mojoBinding.getGroupId() + ":" + mojoBinding.getArtifactId() + ":" + mojoBinding.getGoal();
if ( considerExecutionId )
{
key += ":" + mojoBinding.getExecutionId();
}
return key;
}
public static String createPluginKey( final MojoBinding binding )
{
String result = binding.getGroupId() + ":" + binding.getArtifactId();
if ( binding.getVersion() != null )
{
result += ":" + binding.getVersion();
}
return result;
}
}

View File

@ -615,6 +615,18 @@
<type>boolean</type>
</field>
</fields>
<codeSegments>
<codeSegment>
<version>1.0.0</version>
<code><![CDATA[
public String toString()
{
return getGroupId() + ":" + getArtifactId() + ":" + getVersion() + ":" + getGoal() + ":" + getExecutionId();
}
]]></code>
</codeSegment>
</codeSegments>
</class>
</classes>
</model>

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
@ -17,10 +16,7 @@ software distributed under the License is distributed on an
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
--><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.maven</groupId>