o Restored lifecycle forking

git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@799310 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Benjamin Bentmann 2009-07-30 15:06:59 +00:00
parent 2563edc285
commit 8f5a6bfe6f
5 changed files with 398 additions and 101 deletions

View File

@ -56,6 +56,8 @@ import org.apache.maven.plugin.PluginResolutionException;
import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.Parameter; import org.apache.maven.plugin.descriptor.Parameter;
import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.lifecycle.Execution;
import org.apache.maven.plugin.lifecycle.Phase;
import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProject;
import org.apache.maven.repository.RepositorySystem; import org.apache.maven.repository.RepositorySystem;
import org.apache.maven.wagon.ResourceDoesNotExistException; import org.apache.maven.wagon.ResourceDoesNotExistException;
@ -265,7 +267,10 @@ public class DefaultLifecycleExecutor
} }
public MavenExecutionPlan calculateExecutionPlan( MavenSession session, String... tasks ) public MavenExecutionPlan calculateExecutionPlan( MavenSession session, String... tasks )
throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, CycleDetectedInPluginGraphException, MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException, PluginManagerException throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
CycleDetectedInPluginGraphException, MojoNotFoundException, NoPluginFoundForPrefixException,
InvalidPluginDescriptorException, PluginManagerException, LifecyclePhaseNotFoundException,
LifecycleNotFoundException
{ {
MavenProject project = session.getCurrentProject(); MavenProject project = session.getCurrentProject();
@ -306,7 +311,7 @@ public class DefaultLifecycleExecutor
populateMojoExecutionConfiguration( project, mojoExecution, false ); populateMojoExecutionConfiguration( project, mojoExecution, false );
calculateForkedExecutions( mojoExecution, project, new HashSet<MojoDescriptor>() ); calculateForkedExecutions( mojoExecution, session, project, new HashSet<MojoDescriptor>() );
collectDependencyResolutionScopes( requiredDependencyResolutionScopes, mojoExecution ); collectDependencyResolutionScopes( requiredDependencyResolutionScopes, mojoExecution );
} }
@ -379,49 +384,49 @@ public class DefaultLifecycleExecutor
// 3. Find the mojos associated with the lifecycle given the project packaging (jar lifecycle mapping for the default lifecycle) // 3. Find the mojos associated with the lifecycle given the project packaging (jar lifecycle mapping for the default lifecycle)
// 4. Bind those mojos found in the lifecycle mapping for the packaging to the lifecycle // 4. Bind those mojos found in the lifecycle mapping for the packaging to the lifecycle
// 5. Bind mojos specified in the project itself to the lifecycle // 5. Bind mojos specified in the project itself to the lifecycle
private void calculateExecutionForLifecyclePhase( MavenSession session, List<MojoExecution> lifecyclePlan, String lifecyclePhase ) private void calculateExecutionForLifecyclePhase( MavenSession session, List<MojoExecution> lifecyclePlan,
throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, CycleDetectedInPluginGraphException, MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException String lifecyclePhase )
throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
CycleDetectedInPluginGraphException, MojoNotFoundException, NoPluginFoundForPrefixException,
InvalidPluginDescriptorException, LifecyclePhaseNotFoundException
{ {
MavenProject project = session.getCurrentProject(); Map<String, List<MojoExecution>> phaseToMojoMapping = calculateLifecycleMappings( session, lifecyclePhase );
for ( List<MojoExecution> mojoExecutions : phaseToMojoMapping.values() )
{
lifecyclePlan.addAll( mojoExecutions );
}
}
private Map<String, List<MojoExecution>> calculateLifecycleMappings( MavenSession session, String lifecyclePhase )
throws LifecyclePhaseNotFoundException, PluginNotFoundException, PluginResolutionException,
PluginDescriptorParsingException, CycleDetectedInPluginGraphException, MojoNotFoundException,
InvalidPluginDescriptorException
{
/*
* Determine the lifecycle that corresponds to the given phase.
*/
// 1.
//
// Based on the lifecycle phase we are given, let's find the corresponding lifecycle.
//
Lifecycle lifecycle = phaseToLifecycleMap.get( lifecyclePhase ); Lifecycle lifecycle = phaseToLifecycleMap.get( lifecyclePhase );
// 2.
//
// If we are dealing with the "clean" or "site" lifecycle then there are currently no lifecycle mappings but there are default phases
// that need to be run instead.
//
// Now we need to take into account the packaging type of the project. For a project of type WAR, the lifecycle where mojos are mapped
// on to the given phases in the lifecycle are going to be a little different then, say, a project of type JAR.
//
// 3.
//
// Once we have the lifecycle mapping for the given packaging, we need to know whats phases we need to worry about executing.
//
// Create an ordered Map of the phases in the lifecycle to a list of mojos to execute.
Map<String, List<MojoExecution>> phaseToMojoMapping = new LinkedHashMap<String, List<MojoExecution>>();
// 4.
//TODO: need to separate the lifecycles
if ( lifecycle == null ) if ( lifecycle == null )
{ {
logger.info( "Invalid task '" logger.info( "Invalid task '" + lifecyclePhase + "' : you must specify a valid lifecycle phase"
+ lifecyclePhase + ", or a goal in the format <plugin-prefix>:<goal> or"
+ "' : you must specify a valid lifecycle phase, or a goal in the format plugin:goal or pluginGroupId:pluginArtifactId:pluginVersion:goal" ); + " <plugin-group-id>:<plugin-artifact-id>:<plugin-version>:<goal>" );
throw new MojoNotFoundException( lifecyclePhase, null ); throw new LifecyclePhaseNotFoundException( lifecyclePhase );
} }
/*
* Initialize mapping from lifecycle phase to bound mojos. The key set of this map denotes the phases the caller
* is interested in, i.e. all phases up to and including the specified phase.
*/
Map<String, List<MojoExecution>> lifecycleMappings = new LinkedHashMap<String, List<MojoExecution>>();
for ( String phase : lifecycle.getPhases() ) for ( String phase : lifecycle.getPhases() )
{ {
List<MojoExecution> mojos = new ArrayList<MojoExecution>(); List<MojoExecution> mojoExecutions = new ArrayList<MojoExecution>();
// TODO: remove hard coding // TODO: remove hard coding
if ( phase.equals( "clean" ) ) if ( phase.equals( "clean" ) )
@ -430,21 +435,26 @@ public class DefaultLifecycleExecutor
plugin.setGroupId( "org.apache.maven.plugins" ); plugin.setGroupId( "org.apache.maven.plugins" );
plugin.setArtifactId( "maven-clean-plugin" ); plugin.setArtifactId( "maven-clean-plugin" );
plugin.setVersion( "2.3" ); plugin.setVersion( "2.3" );
mojos.add( new MojoExecution( plugin, "clean", "default-clean" ) ); mojoExecutions.add( new MojoExecution( plugin, "clean", "default-clean" ) );
} }
// This is just just laying out the initial structure of the mojos to run in each phase of the lifecycleMappings.put( phase, mojoExecutions );
// lifecycle. Everything is now done in the project builder correctly so this could likely
// go away shortly. We no longer need to pull out bits from the default lifecycle. The MavenProject
// comes to us intact as it should.
phaseToMojoMapping.put( phase, mojos ); if ( phase.equals( lifecyclePhase ) )
{
break;
}
} }
// 5. Just build up the list of mojos that will execute for every phase. /*
// * Grab plugin executions that are bound to the selected lifecycle phases from project. The effective model of
// This will be useful for having the complete build plan and then we can filter/optimize later. * the project already contains the plugin executions induced by the project's packaging type. Remember, all
// * phases of interest and only those are in the lifecyle mapping, if a phase has no value in the map, we are not
* interested in any of the executions bound to it.
*/
MavenProject project = session.getCurrentProject();
for ( Plugin plugin : project.getBuild().getPlugins() ) for ( Plugin plugin : project.getBuild().getPlugins() )
{ {
for ( PluginExecution execution : plugin.getExecutions() ) for ( PluginExecution execution : plugin.getExecutions() )
@ -452,20 +462,15 @@ public class DefaultLifecycleExecutor
// if the phase is specified then I don't have to go fetch the plugin yet and pull it down // if the phase is specified then I don't have to go fetch the plugin yet and pull it down
// to examine the phase it is associated to. // to examine the phase it is associated to.
if ( execution.getPhase() != null ) if ( execution.getPhase() != null )
{
List<MojoExecution> mojoExecutions = lifecycleMappings.get( execution.getPhase() );
if ( mojoExecutions != null )
{ {
for ( String goal : execution.getGoals() ) for ( String goal : execution.getGoals() )
{ {
if ( phaseToMojoMapping.get( execution.getPhase() ) == null )
{
// This is happening because executions in the POM are getting mixed into the clean lifecycle
// So for the lifecycle mapping we need a map with the phases as keys so we can easily check
// if this phase belongs to the given lifecycle. this shows the system is messed up. this
// shouldn't happen.
phaseToMojoMapping.put( execution.getPhase(), new ArrayList<MojoExecution>() );
}
MojoExecution mojoExecution = new MojoExecution( plugin, goal, execution.getId() ); MojoExecution mojoExecution = new MojoExecution( plugin, goal, execution.getId() );
phaseToMojoMapping.get( execution.getPhase() ).add( mojoExecution ); mojoExecutions.add( mojoExecution );
}
} }
} }
// if not then i need to grab the mojo descriptor and look at the phase that is specified // if not then i need to grab the mojo descriptor and look at the phase that is specified
@ -473,37 +478,29 @@ public class DefaultLifecycleExecutor
{ {
for ( String goal : execution.getGoals() ) for ( String goal : execution.getGoals() )
{ {
MojoDescriptor mojoDescriptor = pluginManager.getMojoDescriptor( plugin, goal, session.getLocalRepository(), project.getPluginArtifactRepositories() ); MojoDescriptor mojoDescriptor =
pluginManager.getMojoDescriptor( plugin, goal, session.getLocalRepository(),
project.getPluginArtifactRepositories() );
if ( mojoDescriptor.getPhase() != null && phaseToMojoMapping.get( mojoDescriptor.getPhase() ) != null ) List<MojoExecution> mojoExecutions = lifecycleMappings.get( mojoDescriptor.getPhase() );
if ( mojoExecutions != null )
{ {
MojoExecution mojoExecution = new MojoExecution( plugin, goal, execution.getId() ); MojoExecution mojoExecution = new MojoExecution( plugin, goal, execution.getId() );
phaseToMojoMapping.get( mojoDescriptor.getPhase() ).add( mojoExecution ); mojoExecutions.add( mojoExecution );
} }
} }
} }
} }
} }
// 6. return lifecycleMappings;
//
// We are only interested in the phases that correspond to the lifecycle we are trying to run. If we are running the "clean"
// lifecycle we are not interested in goals -- like "generate-sources -- that belong to the default lifecycle.
//
for ( String phase : phaseToMojoMapping.keySet() )
{
lifecyclePlan.addAll( phaseToMojoMapping.get( phase ) );
if ( phase.equals( lifecyclePhase ) )
{
break;
}
}
} }
private void calculateForkedExecutions( MojoExecution mojoExecution, MavenProject project, private void calculateForkedExecutions( MojoExecution mojoExecution, MavenSession session, MavenProject project,
Collection<MojoDescriptor> alreadyForkedExecutions ) Collection<MojoDescriptor> alreadyForkedExecutions )
throws MojoNotFoundException throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
PluginDescriptorParsingException, CycleDetectedInPluginGraphException, NoPluginFoundForPrefixException,
InvalidPluginDescriptorException, LifecyclePhaseNotFoundException, LifecycleNotFoundException
{ {
MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor(); MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
@ -516,8 +513,115 @@ public class DefaultLifecycleExecutor
if ( StringUtils.isNotEmpty( mojoDescriptor.getExecutePhase() ) ) if ( StringUtils.isNotEmpty( mojoDescriptor.getExecutePhase() ) )
{ {
// TODO String forkedPhase = mojoDescriptor.getExecutePhase();
Map<String, List<MojoExecution>> lifecycleMappings = calculateLifecycleMappings( session, forkedPhase );
for ( List<MojoExecution> forkedExecutions : lifecycleMappings.values() )
{
for ( MojoExecution forkedExecution : forkedExecutions )
{
if ( forkedExecution.getMojoDescriptor() == null )
{
MojoDescriptor forkedMojoDescriptor =
pluginManager.getMojoDescriptor( forkedExecution.getPlugin(), forkedExecution.getGoal(),
session.getLocalRepository(),
project.getPluginArtifactRepositories() );
forkedExecution.setMojoDescriptor( forkedMojoDescriptor );
}
populateMojoExecutionConfiguration( project, forkedExecution, false );
}
}
String forkedLifecycle = mojoDescriptor.getExecuteLifecycle();
if ( StringUtils.isNotEmpty( forkedLifecycle ) )
{
org.apache.maven.plugin.lifecycle.Lifecycle lifecycleOverlay;
try
{
lifecycleOverlay = pluginDescriptor.getLifecycleMapping( forkedLifecycle );
}
catch ( IOException e )
{
throw new PluginDescriptorParsingException( pluginDescriptor.getPlugin(), e );
}
catch ( XmlPullParserException e )
{
throw new PluginDescriptorParsingException( pluginDescriptor.getPlugin(), e );
}
if ( lifecycleOverlay == null )
{
throw new LifecycleNotFoundException( forkedLifecycle );
}
for ( Phase phase : lifecycleOverlay.getPhases() )
{
List<MojoExecution> forkedExecutions = lifecycleMappings.get( phase.getId() );
if ( forkedExecutions != null )
{
for ( Execution execution : phase.getExecutions() )
{
for ( String goal : execution.getGoals() )
{
MojoDescriptor forkedMojoDescriptor;
if ( goal.indexOf( ':' ) < 0 )
{
forkedMojoDescriptor = pluginDescriptor.getMojo( goal );
if ( forkedMojoDescriptor == null )
{
throw new MojoNotFoundException( goal, pluginDescriptor );
}
}
else
{
forkedMojoDescriptor = getMojoDescriptor( goal, session );
}
MojoExecution forkedExecution =
new MojoExecution( forkedMojoDescriptor, mojoExecution.getExecutionId() );
Xpp3Dom forkedConfiguration = (Xpp3Dom) execution.getConfiguration();
forkedExecution.setConfiguration( forkedConfiguration );
populateMojoExecutionConfiguration( project, forkedExecution, true );
forkedExecutions.add( forkedExecution );
}
}
Xpp3Dom phaseConfiguration = (Xpp3Dom) phase.getConfiguration();
if ( phaseConfiguration != null )
{
for ( MojoExecution forkedExecution : forkedExecutions )
{
Xpp3Dom executionConfiguration = forkedExecution.getConfiguration();
Xpp3Dom mergedConfiguration =
Xpp3Dom.mergeXpp3Dom( phaseConfiguration, executionConfiguration );
forkedExecution.setConfiguration( mergedConfiguration );
}
}
}
}
}
for ( List<MojoExecution> forkedExecutions : lifecycleMappings.values() )
{
for ( MojoExecution forkedExecution : forkedExecutions )
{
calculateForkedExecutions( forkedExecution, session, project, alreadyForkedExecutions );
mojoExecution.addForkedExecution( forkedExecution );
}
}
} }
else if ( StringUtils.isNotEmpty( mojoDescriptor.getExecuteGoal() ) ) else if ( StringUtils.isNotEmpty( mojoDescriptor.getExecuteGoal() ) )
{ {
@ -533,7 +637,7 @@ public class DefaultLifecycleExecutor
populateMojoExecutionConfiguration( project, forkedExecution, true ); populateMojoExecutionConfiguration( project, forkedExecution, true );
calculateForkedExecutions( forkedExecution, project, alreadyForkedExecutions ); calculateForkedExecutions( forkedExecution, session, project, alreadyForkedExecutions );
mojoExecution.addForkedExecution( forkedExecution ); mojoExecution.addForkedExecution( forkedExecution );
} }
@ -555,7 +659,7 @@ public class DefaultLifecycleExecutor
Plugin plugin = project.getPlugin( g + ":" + a ); Plugin plugin = project.getPlugin( g + ":" + a );
if ( plugin != null ) if ( plugin != null && StringUtils.isNotEmpty( mojoExecution.getExecutionId() ) )
{ {
for ( PluginExecution e : plugin.getExecutions() ) for ( PluginExecution e : plugin.getExecutions() )
{ {
@ -565,7 +669,10 @@ public class DefaultLifecycleExecutor
Xpp3Dom mojoConfiguration = extractMojoConfiguration( executionConfiguration, mojoExecution.getMojoDescriptor() ); Xpp3Dom mojoConfiguration = extractMojoConfiguration( executionConfiguration, mojoExecution.getMojoDescriptor() );
mojoExecution.setConfiguration( mojoConfiguration ); Xpp3Dom mergedConfiguration =
Xpp3Dom.mergeXpp3Dom( mojoExecution.getConfiguration(), mojoConfiguration );
mojoExecution.setConfiguration( mergedConfiguration );
return; return;
} }
@ -576,16 +683,18 @@ public class DefaultLifecycleExecutor
{ {
Xpp3Dom defaultDom = convert( mojoExecution.getMojoDescriptor() ); Xpp3Dom defaultDom = convert( mojoExecution.getMojoDescriptor() );
Xpp3Dom mojoDom = defaultDom;
if ( plugin != null && plugin.getConfiguration() != null ) if ( plugin != null && plugin.getConfiguration() != null )
{ {
Xpp3Dom projectDom = (Xpp3Dom) plugin.getConfiguration(); Xpp3Dom projectDom = (Xpp3Dom) plugin.getConfiguration();
projectDom = extractMojoConfiguration( projectDom, mojoExecution.getMojoDescriptor() ); projectDom = extractMojoConfiguration( projectDom, mojoExecution.getMojoDescriptor() );
mojoExecution.setConfiguration( Xpp3Dom.mergeXpp3Dom( projectDom, defaultDom, Boolean.TRUE ) ); mojoDom = Xpp3Dom.mergeXpp3Dom( projectDom, defaultDom, Boolean.TRUE );
}
else
{
mojoExecution.setConfiguration( defaultDom );
} }
mojoDom = Xpp3Dom.mergeXpp3Dom( mojoExecution.getConfiguration(), mojoDom );
mojoExecution.setConfiguration( mojoDom );
} }
} }
@ -699,7 +808,7 @@ public class DefaultLifecycleExecutor
plugin.setArtifactId( tok.nextToken() ); plugin.setArtifactId( tok.nextToken() );
goal = tok.nextToken(); goal = tok.nextToken();
} }
if ( numTokens == 2 ) else if ( numTokens == 2 )
{ {
// We have a prefix and goal // We have a prefix and goal
// //

View File

@ -49,7 +49,10 @@ public interface LifecycleExecutor
* @throws LifecycleExecutionException * @throws LifecycleExecutionException
*/ */
MavenExecutionPlan calculateExecutionPlan( MavenSession session, String... tasks ) MavenExecutionPlan calculateExecutionPlan( MavenSession session, String... tasks )
throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, CycleDetectedInPluginGraphException, MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException, PluginManagerException; throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
CycleDetectedInPluginGraphException, MojoNotFoundException, NoPluginFoundForPrefixException,
InvalidPluginDescriptorException, PluginManagerException, LifecyclePhaseNotFoundException,
LifecycleNotFoundException;
// For a given project packaging find all the plugins that are bound to any registered // For a given project packaging find all the plugins that are bound to any registered
// lifecycles. The project builder needs to now what default plugin information needs to be // lifecycles. The project builder needs to now what default plugin information needs to be

View File

@ -0,0 +1,54 @@
package org.apache.maven.lifecycle;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* Signals a failure to locate a lifecycle.
*
* @author Benjamin Bentmann
*/
public class LifecycleNotFoundException
extends Exception
{
private final String lifecycleId;
/**
* Creates a new exception to indicate that the specified lifecycle is unknown.
*
* @param lifecycleId The identifier of the lifecycle that could not be located, may be {@code null}.
*/
public LifecycleNotFoundException( String lifecycleId )
{
super( "Unknown lifecycle " + lifecycleId );
this.lifecycleId = ( lifecycleId != null ) ? lifecycleId : "";
}
/**
* Gets the identifier of the lifecycle that was not found.
*
* @return The identifier of the lifecycle that was not found, never {@code null}.
*/
public String getLifecycleId()
{
return lifecycleId;
}
}

View File

@ -0,0 +1,54 @@
package org.apache.maven.lifecycle;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* Signals a failure to locate the lifecycle for some phase.
*
* @author Benjamin Bentmann
*/
public class LifecyclePhaseNotFoundException
extends Exception
{
private final String lifecyclePhase;
/**
* Creates a new exception to indicate that the specified lifecycle phase is not defined by any known lifecycle.
*
* @param lifecyclePhase The name of the lifecycle phase that could not be located, may be {@code null}.
*/
public LifecyclePhaseNotFoundException( String lifecyclePhase )
{
super( "Unknown lifecycle phase " + lifecyclePhase );
this.lifecyclePhase = ( lifecyclePhase != null ) ? lifecyclePhase : "";
}
/**
* Gets the lifecycle phase that was not found.
*
* @return The lifecycle phase that was not found, never {@code null}.
*/
public String getLifecyclePhase()
{
return lifecyclePhase;
}
}

View File

@ -19,7 +19,15 @@ package org.apache.maven.plugin.descriptor;
* under the License. * under the License.
*/ */
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -28,8 +36,14 @@ import java.util.Set;
import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.ArtifactUtils; import org.apache.maven.artifact.ArtifactUtils;
import org.apache.maven.model.Plugin; import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.lifecycle.Lifecycle;
import org.apache.maven.plugin.lifecycle.LifecycleConfiguration;
import org.apache.maven.plugin.lifecycle.io.xpp3.LifecycleMappingsXpp3Reader;
import org.codehaus.plexus.classworlds.realm.ClassRealm; import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.component.repository.ComponentSetDescriptor; import org.codehaus.plexus.component.repository.ComponentSetDescriptor;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
/** /**
* @author Jason van Zyl * @author Jason van Zyl
@ -37,6 +51,9 @@ import org.codehaus.plexus.component.repository.ComponentSetDescriptor;
public class PluginDescriptor public class PluginDescriptor
extends ComponentSetDescriptor extends ComponentSetDescriptor
{ {
private static final String LIFECYCLE_DESCRIPTOR = "META-INF/maven/lifecycle.xml";
private String groupId; private String groupId;
private String artifactId; private String artifactId;
@ -49,14 +66,14 @@ public class PluginDescriptor
private boolean inheritedByDefault = true; private boolean inheritedByDefault = true;
private List artifacts; private List<Artifact> artifacts;
private ClassRealm classRealm; private ClassRealm classRealm;
// calculated on-demand. // calculated on-demand.
private Map artifactMap; private Map<String, Artifact> artifactMap;
private Set introducedDependencyArtifacts; private Set<Artifact> introducedDependencyArtifacts;
private String name; private String name;
@ -66,6 +83,8 @@ public class PluginDescriptor
private Artifact pluginArtifact; private Artifact pluginArtifact;
private Map<String, Lifecycle> lifecycleMappings;
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// //
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
@ -208,12 +227,12 @@ public class PluginDescriptor
this.inheritedByDefault = inheritedByDefault; this.inheritedByDefault = inheritedByDefault;
} }
public List getArtifacts() public List<Artifact> getArtifacts()
{ {
return artifacts; return artifacts;
} }
public void setArtifacts( List artifacts ) public void setArtifacts( List<Artifact> artifacts )
{ {
this.artifacts = artifacts; this.artifacts = artifacts;
@ -221,7 +240,7 @@ public class PluginDescriptor
artifactMap = null; artifactMap = null;
} }
public Map getArtifactMap() public Map<String, Artifact> getArtifactMap()
{ {
if ( artifactMap == null ) if ( artifactMap == null )
{ {
@ -280,14 +299,15 @@ public class PluginDescriptor
return classRealm; return classRealm;
} }
public void setIntroducedDependencyArtifacts( Set introducedDependencyArtifacts ) public void setIntroducedDependencyArtifacts( Set<Artifact> introducedDependencyArtifacts )
{ {
this.introducedDependencyArtifacts = introducedDependencyArtifacts; this.introducedDependencyArtifacts = introducedDependencyArtifacts;
} }
public Set getIntroducedDependencyArtifacts() public Set<Artifact> getIntroducedDependencyArtifacts()
{ {
return introducedDependencyArtifacts != null ? introducedDependencyArtifacts : Collections.EMPTY_SET; return ( introducedDependencyArtifacts != null ) ? introducedDependencyArtifacts
: Collections.<Artifact> emptySet();
} }
public void setName( String name ) public void setName( String name )
@ -329,4 +349,61 @@ public class PluginDescriptor
{ {
this.pluginArtifact = pluginArtifact; this.pluginArtifact = pluginArtifact;
} }
public Lifecycle getLifecycleMapping( String lifecycleId )
throws IOException, XmlPullParserException
{
if ( lifecycleMappings == null )
{
LifecycleConfiguration lifecycleConfiguration;
Reader reader = null;
try
{
reader = ReaderFactory.newXmlReader( getDescriptorStream( LIFECYCLE_DESCRIPTOR ) );
lifecycleConfiguration = new LifecycleMappingsXpp3Reader().read( reader );
}
finally
{
IOUtil.close( reader );
}
lifecycleMappings = new HashMap<String, Lifecycle>();
for ( Lifecycle lifecycle : lifecycleConfiguration.getLifecycles() )
{
lifecycleMappings.put( lifecycle.getId(), lifecycle );
}
}
return lifecycleMappings.get( lifecycleId );
}
private InputStream getDescriptorStream( String descriptor )
throws IOException
{
File pluginFile = ( pluginArtifact != null ) ? pluginArtifact.getFile() : null;
if ( pluginFile == null )
{
throw new IllegalStateException( "plugin main artifact has not been resolved" );
}
if ( pluginFile.isFile() )
{
try
{
return new URL( "jar:" + pluginFile.toURI() + "!/" + descriptor ).openStream();
}
catch ( MalformedURLException e )
{
throw new IllegalStateException( e );
}
}
else
{
return new FileInputStream( new File( pluginFile, descriptor ) );
}
}
} }