From d25dd879f3559176660cc581f7abaec92c7d5166 Mon Sep 17 00:00:00 2001 From: John Dennis Casey Date: Thu, 31 May 2007 23:11:47 +0000 Subject: [PATCH] OPEN - issue MNG-3027: forked execution does not get configuration from the POM http://jira.codehaus.org/browse/MNG-3027 Adding reporting section to sources of plugin configuration when mojos are forked from a report mojo. Also, improving detection/addition of report mojos from a plugin, when no report-set is defined. git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@543308 13f79535-47bb-0310-9956-ffa450edef68 --- .../lifecycle/DefaultLifecycleExecutor.java | 8 +- .../maven/lifecycle/binding/BindingUtils.java | 93 ++++++++++--- .../DefaultLifecycleBindingManager.java | 70 +++++----- .../binding/DefaultMojoBindingFactory.java | 20 +-- .../binding/LifecycleBindingManager.java | 6 +- .../lifecycle/binding/MojoBindingFactory.java | 6 +- .../maven/lifecycle/plan/BuildPlan.java | 127 +++++++++--------- .../lifecycle/plan/DefaultBuildPlanner.java | 29 ++-- .../statemgmt/ResolveLateBoundPluginMojo.java | 4 +- .../main/resources/META-INF/maven/plugin.xml | 8 ++ .../DefaultMojoBindingFactoryTest.java | 12 +- 11 files changed, 231 insertions(+), 152 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java b/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java index ebe4331f11..e282d8c17e 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java @@ -95,7 +95,7 @@ public class DefaultLifecycleExecutor extends AbstractLogEnabled implements Life /** * Execute a task. Each task may be a phase in the lifecycle or the execution of a mojo. - * + * * @param session * @param rm * @param dispatcher @@ -547,7 +547,7 @@ public class DefaultLifecycleExecutor extends AbstractLogEnabled implements Life /** * @todo Not particularly happy about this. Would like WagonManager and ArtifactTypeHandlerManager to be able to * 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( final MavenSession session ) @@ -644,7 +644,9 @@ public class DefaultLifecycleExecutor extends AbstractLogEnabled implements Life final MavenProject project ) throws LifecycleSpecificationException, PluginLoaderException, LifecycleLoaderException { - MojoBinding binding = mojoBindingFactory.parseMojoBinding( task, project, true ); + // we don't need to include report configuration here, since we're just looking for + // an @aggregator flag... + MojoBinding binding = mojoBindingFactory.parseMojoBinding( task, project, true, false ); PluginDescriptor descriptor = pluginLoader.loadPlugin( binding, project ); MojoDescriptor mojoDescriptor = descriptor.getMojo( binding.getGoal() ); diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/binding/BindingUtils.java b/maven-core/src/main/java/org/apache/maven/lifecycle/binding/BindingUtils.java index 8d2f3c0cc8..4e70fc99d3 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/binding/BindingUtils.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/binding/BindingUtils.java @@ -11,6 +11,7 @@ import org.apache.maven.model.PluginExecution; import org.apache.maven.model.PluginManagement; import org.apache.maven.model.ReportPlugin; import org.apache.maven.model.ReportSet; +import org.apache.maven.model.Reporting; import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.project.MavenProject; import org.apache.maven.project.ModelUtils; @@ -37,7 +38,7 @@ final class BindingUtils static Map buildPluginMap( MavenProject project ) { Map pluginMap = new HashMap(); - + if ( project != null ) { Build build = project.getBuild(); @@ -55,15 +56,41 @@ final class BindingUtils return pluginMap; } + /** + * Builds a mapping of groupId:artifactId --> ReportPlugin from the POM. If a plugin is listed + * without a groupId, the {@link BindingUtils#createPluginKey(Plugin)} method will fill it in + * using org.apache.maven.plugins. + */ + static Map buildReportPluginMap( MavenProject project ) + { + Map pluginMap = new HashMap(); + + if ( project != null ) + { + Reporting reporting = project.getReporting(); + if ( reporting != null ) + { + for ( Iterator it = reporting.getPlugins().iterator(); it.hasNext(); ) + { + ReportPlugin plugin = (ReportPlugin) it.next(); + + pluginMap.put( createPluginKey( plugin.getGroupId(), plugin.getArtifactId() ), plugin ); + } + } + } + + return pluginMap; + } + /** * Builds a mapping of groupId:artifactId --> Plugin from a PluginContainer, such as the build - * or pluginManagement section of a POM. If a plugin is listed without a groupId, the + * or pluginManagement section of a POM. If a plugin is listed without a groupId, the * {@link BindingUtils#createPluginKey(Plugin)} method will fill it in using org.apache.maven.plugins. */ static Map buildPluginMap( PluginContainer pluginContainer ) { Map pluginMap = new HashMap(); - + if ( pluginContainer != null ) { for ( Iterator it = pluginContainer.getPlugins().iterator(); it.hasNext(); ) @@ -87,7 +114,7 @@ final class BindingUtils } /** - * Create a key for use in looking up Plugin instances from mappings. The key consists of + * Create a key for use in looking up Plugin instances from mappings. The key consists of * groupId:artifactId, where groupId == org.apache.maven.plugins if the supplied groupId * value == null. */ @@ -102,7 +129,7 @@ final class BindingUtils */ static Object mergeConfigurations( ReportPlugin reportPlugin, ReportSet reportSet ) { - if ( reportPlugin == null && reportSet == null ) + if ( ( reportPlugin == null ) && ( reportSet == null ) ) { return null; } @@ -121,12 +148,12 @@ final class BindingUtils } /** - * Merge the Plugin and PluginExecution configurations, with the PluginExecution configuration + * Merge the Plugin and PluginExecution configurations, with the PluginExecution configuration * taking precedence. */ static Object mergeConfigurations( Plugin plugin, PluginExecution execution ) { - if ( plugin == null && execution == null ) + if ( ( plugin == null ) && ( execution == null ) ) { return null; } @@ -167,15 +194,17 @@ final class BindingUtils return Xpp3Dom.mergeXpp3Dom( new Xpp3Dom( dominantConfig ), recessiveConfig ); } } - + /** * Inject any plugin configuration available from the specified POM into the MojoBinding, after * first merging in the applicable configuration from the POM's pluginManagement section. */ - static void injectProjectConfiguration( MojoBinding binding, MavenProject project ) + static void injectProjectConfiguration( MojoBinding binding, MavenProject project, boolean includeReportConfig ) { Map pluginMap = buildPluginMap( project ); - Plugin plugin = (Plugin) pluginMap.get( createPluginKey( binding.getGroupId(), binding.getArtifactId() ) ); + + String key = createPluginKey( binding.getGroupId(), binding.getArtifactId() ); + Plugin plugin = (Plugin) pluginMap.get( key ); if ( plugin == null ) { @@ -183,17 +212,41 @@ final class BindingUtils plugin.setGroupId( binding.getGroupId() ); plugin.setArtifactId( binding.getArtifactId() ); } - + injectPluginManagementInfo( plugin, project ); PluginExecution exec = (PluginExecution) plugin.getExecutionsAsMap().get( binding.getExecutionId() ); - binding.setConfiguration( mergeConfigurations( plugin, exec ) ); + Object configuration = mergeConfigurations( plugin, exec ); + + if ( includeReportConfig ) + { + ReportPlugin reportPlugin = (ReportPlugin) BindingUtils.buildReportPluginMap( project ).get( key ); + if ( reportPlugin != null ) + { + Map reportSets = reportPlugin.getReportSetsAsMap(); + + ReportSet reportSet = null; + if ( ( reportSets != null ) && ( exec != null ) ) + { + reportSet = (ReportSet) reportSets.get( exec.getId() ); + } + + Object reportConfig = BindingUtils.mergeConfigurations( reportPlugin, reportSet ); + + // NOTE: This looks weird, but we must retain some consistency with + // dominance of plugin configs, regardless of whether they're report + // mojos or not. + configuration = mergeRawConfigurations( reportConfig, configuration ); + } + } + + binding.setConfiguration( configuration ); } /** - * Inject any plugin configuration available from the specified POM into the MojoBindings - * present in the given LifecycleBindings instance, after first merging in the configuration + * Inject any plugin configuration available from the specified POM into the MojoBindings + * present in the given LifecycleBindings instance, after first merging in the configuration * from the POM's pluginManagement section. */ static void injectProjectConfiguration( LifecycleBindings bindings, MavenProject project ) @@ -221,7 +274,7 @@ final class BindingUtils plugin.setGroupId( mojo.getGroupId() ); plugin.setArtifactId( mojo.getArtifactId() ); } - + injectPluginManagementInfo( plugin, project ); PluginExecution exec = (PluginExecution) plugin.getExecutionsAsMap().get( mojo.getExecutionId() ); @@ -242,24 +295,24 @@ final class BindingUtils { return; } - + Build build = project.getBuild(); if ( build == null ) { return; } - + PluginManagement plugMgmt = build.getPluginManagement(); if ( plugMgmt == null ) { return; } - + Map plugMgmtMap = buildPluginMap( plugMgmt ); - + String key = createPluginKey( plugin ); Plugin mgmtPlugin = (Plugin) plugMgmtMap.get( key ); - + if ( mgmtPlugin != null ) { ModelUtils.mergePluginDefinitions( plugin, mgmtPlugin, false ); diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/binding/DefaultLifecycleBindingManager.java b/maven-core/src/main/java/org/apache/maven/lifecycle/binding/DefaultLifecycleBindingManager.java index 1b048762c4..6f2bec8916 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/binding/DefaultLifecycleBindingManager.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/binding/DefaultLifecycleBindingManager.java @@ -18,6 +18,8 @@ import org.apache.maven.plugin.lifecycle.Lifecycle; import org.apache.maven.plugin.loader.PluginLoader; import org.apache.maven.plugin.loader.PluginLoaderException; import org.apache.maven.project.MavenProject; +import org.apache.maven.reporting.MavenReport; +import org.codehaus.plexus.classworlds.realm.ClassRealm; import org.codehaus.plexus.collections.ActiveMap; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; import org.codehaus.plexus.logging.LogEnabled; @@ -29,18 +31,18 @@ import java.io.IOException; import java.util.ArrayList; 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. - * + * * @author jdcasey - * + * */ -public class DefaultLifecycleBindingManager implements LifecycleBindingManager, LogEnabled +public class DefaultLifecycleBindingManager + implements LifecycleBindingManager, LogEnabled { private ActiveMap bindingsByPackaging; @@ -314,7 +316,8 @@ public class DefaultLifecycleBindingManager implements LifecycleBindingManager, * plugin. Inject mojo configuration from the POM into all appropriate MojoBinding instances. */ public LifecycleBindings getPluginLifecycleOverlay( final PluginDescriptor pluginDescriptor, - final String lifecycleId, final MavenProject project ) + final String lifecycleId, final MavenProject project, + final boolean includeReportConfig ) throws LifecycleLoaderException, LifecycleSpecificationException { Lifecycle lifecycleOverlay = null; @@ -381,7 +384,7 @@ public class DefaultLifecycleBindingManager implements LifecycleBindingManager, MojoBinding binding; if ( goal.indexOf( ":" ) > 0 ) { - binding = mojoBindingFactory.parseMojoBinding( goal, project, false ); + binding = mojoBindingFactory.parseMojoBinding( goal, project, false, includeReportConfig ); } else { @@ -447,7 +450,7 @@ public class DefaultLifecycleBindingManager implements LifecycleBindingManager, { if ( project.getModel().getReports() != null ) { - logger.error( "Plugin contains a section: this is IGNORED - please use instead." ); + logger.warn( "Plugin contains a section: this is IGNORED - please use instead." ); } List reportPlugins = getReportPluginsForProject( project ); @@ -553,14 +556,25 @@ public class DefaultLifecycleBindingManager implements LifecycleBindingManager, + e.getMessage(), e ); } - String pluginKey = BindingUtils.createPluginKey( reportPlugin.getGroupId(), reportPlugin.getArtifactId() ); - Plugin plugin = (Plugin) BindingUtils.buildPluginMap( project ).get( pluginKey ); - List reports = new ArrayList(); for ( Iterator i = pluginDescriptor.getMojos().iterator(); i.hasNext(); ) { MojoDescriptor mojoDescriptor = (MojoDescriptor) i.next(); + + // FIXME: Can't we be smarter about what is and what is not a report??? + try + { + if ( !isReport( mojoDescriptor ) ) + { + continue; + } + } + catch ( ClassNotFoundException e ) + { + throw new LifecycleLoaderException( "Failed while verifying that mojo: " + mojoDescriptor.getId() + " is a report mojo. Reason: " + e.getMessage(), e ); + } + // 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() ) ) @@ -579,29 +593,7 @@ public class DefaultLifecycleBindingManager implements LifecycleBindingManager, binding.setExecutionId( id ); binding.setOrigin( "POM" ); - Object reportConfig = BindingUtils.mergeConfigurations( reportPlugin, reportSet ); - - if ( plugin == null ) - { - plugin = new Plugin(); - plugin.setGroupId( pluginDescriptor.getGroupId() ); - plugin.setArtifactId( pluginDescriptor.getArtifactId() ); - } - - BindingUtils.injectPluginManagementInfo( plugin, project ); - - Map execMap = plugin.getExecutionsAsMap(); - PluginExecution exec = (PluginExecution) execMap.get( id ); - - Object pluginConfig = plugin.getConfiguration(); - if ( exec != null ) - { - pluginConfig = BindingUtils.mergeConfigurations( plugin, exec ); - } - - reportConfig = BindingUtils.mergeRawConfigurations( reportConfig, pluginConfig ); - - binding.setConfiguration( reportConfig ); + BindingUtils.injectProjectConfiguration( binding, project, true ); reports.add( binding ); } @@ -609,4 +601,16 @@ public class DefaultLifecycleBindingManager implements LifecycleBindingManager, return reports; } + private boolean isReport( MojoDescriptor mojoDescriptor ) + throws ClassNotFoundException + { + ClassRealm classRealm = mojoDescriptor.getPluginDescriptor().getClassRealm(); + String impl = mojoDescriptor.getImplementation(); + + Class mojoClass = classRealm.loadClass( impl ); + Class reportClass = classRealm.loadClass( MavenReport.class.getName() ); + + return reportClass.isAssignableFrom( mojoClass ); + } + } diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/binding/DefaultMojoBindingFactory.java b/maven-core/src/main/java/org/apache/maven/lifecycle/binding/DefaultMojoBindingFactory.java index 0e6b554565..e596547dfd 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/binding/DefaultMojoBindingFactory.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/binding/DefaultMojoBindingFactory.java @@ -13,7 +13,7 @@ import java.util.StringTokenizer; /** * Responsible for constructing or parsing MojoBinding instances from one of several sources, potentially * using the {@link PluginLoader} to resolve any plugin prefixes first. - * + * * @author jdcasey * */ @@ -28,7 +28,7 @@ public class DefaultMojoBindingFactory * If a plugin-prefix is allowed and used, resolve the prefix and use the resulting PluginDescriptor * to set groupId and artifactId on the MojoBinding instance. */ - public MojoBinding parseMojoBinding( String bindingSpec, MavenProject project, boolean allowPrefixReference ) + public MojoBinding parseMojoBinding( String bindingSpec, MavenProject project, boolean allowPrefixReference, boolean includeReportConfig ) throws LifecycleSpecificationException, LifecycleLoaderException { StringTokenizer tok = new StringTokenizer( bindingSpec, ":" ); @@ -61,9 +61,9 @@ public class DefaultMojoBindingFactory } binding = createMojoBinding( pluginDescriptor.getGroupId(), pluginDescriptor.getArtifactId(), - pluginDescriptor.getVersion(), tok.nextToken(), project ); + pluginDescriptor.getVersion(), tok.nextToken(), project, includeReportConfig ); } - else if ( numTokens == 3 || numTokens == 4 ) + else if ( ( numTokens == 3 ) || ( numTokens == 4 ) ) { binding = new MojoBinding(); @@ -78,7 +78,7 @@ public class DefaultMojoBindingFactory String goal = tok.nextToken(); - binding = createMojoBinding( groupId, artifactId, version, goal, project ); + binding = createMojoBinding( groupId, artifactId, version, goal, project, includeReportConfig ); } else { @@ -95,7 +95,7 @@ public class DefaultMojoBindingFactory * Create a new MojoBinding instance with the specified information, and inject POM configurations * appropriate to that mojo before returning it. */ - public MojoBinding createMojoBinding( String groupId, String artifactId, String version, String goal, MavenProject project ) + public MojoBinding createMojoBinding( String groupId, String artifactId, String version, String goal, MavenProject project, boolean includeReportConfig ) { MojoBinding binding = new MojoBinding(); @@ -104,7 +104,7 @@ public class DefaultMojoBindingFactory binding.setVersion( version ); binding.setGoal( goal ); - BindingUtils.injectProjectConfiguration( binding, project ); + BindingUtils.injectProjectConfiguration( binding, project, includeReportConfig ); return binding; } @@ -119,15 +119,15 @@ public class DefaultMojoBindingFactory { try { - return parseMojoBinding( bindingSpec, null, false ); + return parseMojoBinding( bindingSpec, null, false, false ); } catch ( LifecycleLoaderException e ) { IllegalStateException error = new IllegalStateException( e.getMessage() + "\n\nTHIS SHOULD BE IMPOSSIBLE DUE TO THE USAGE OF THE PLUGIN-LOADER." ); - + error.initCause( e ); - + throw error; } } diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/binding/LifecycleBindingManager.java b/maven-core/src/main/java/org/apache/maven/lifecycle/binding/LifecycleBindingManager.java index df881c2923..3eefd40291 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/binding/LifecycleBindingManager.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/binding/LifecycleBindingManager.java @@ -12,9 +12,9 @@ import java.util.List; * 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 { @@ -45,7 +45,7 @@ public interface LifecycleBindingManager * plugin. Inject mojo configuration from the POM into all appropriate MojoBinding instances. */ LifecycleBindings getPluginLifecycleOverlay( PluginDescriptor pluginDescriptor, String lifecycleId, - MavenProject project ) + MavenProject project, boolean includeReportConfig ) throws LifecycleLoaderException, LifecycleSpecificationException; /** diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/binding/MojoBindingFactory.java b/maven-core/src/main/java/org/apache/maven/lifecycle/binding/MojoBindingFactory.java index 95dab64cec..3d216fdbb8 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/binding/MojoBindingFactory.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/binding/MojoBindingFactory.java @@ -9,7 +9,7 @@ import org.apache.maven.project.MavenProject; /** * Responsible for constructing or parsing MojoBinding instances from one of several sources, potentially * using the {@link PluginLoader} to resolve any plugin prefixes first. - * + * * @author jdcasey * */ @@ -23,14 +23,14 @@ public interface MojoBindingFactory * If a plugin-prefix is allowed and used, resolve the prefix and use the resulting PluginDescriptor * to set groupId and artifactId on the MojoBinding instance. */ - MojoBinding parseMojoBinding( String bindingSpec, MavenProject project, boolean allowPrefixReference ) + MojoBinding parseMojoBinding( String bindingSpec, MavenProject project, boolean allowPrefixReference, boolean includeReportConfig ) throws LifecycleSpecificationException, LifecycleLoaderException; /** * Create a new MojoBinding instance with the specified information, and inject POM configurations * appropriate to that mojo before returning it. */ - MojoBinding createMojoBinding( String groupId, String artifactId, String version, String goal, MavenProject project ); + MojoBinding createMojoBinding( String groupId, String artifactId, String version, String goal, MavenProject project, boolean includeReportConfig ); /** * Simplified version of {@link MojoBindingFactory#parseMojoBinding(String, MavenProject, boolean)} diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/plan/BuildPlan.java b/maven-core/src/main/java/org/apache/maven/lifecycle/plan/BuildPlan.java index f933e2eaa1..48d8ca93b1 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/plan/BuildPlan.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/plan/BuildPlan.java @@ -23,7 +23,9 @@ public class BuildPlan private final List tasks; - private final Map forks; + private final Map forkedDirectInvocations; + + private final Map forkedPhases; private final List lateBoundMojos; @@ -43,16 +45,18 @@ public class BuildPlan { this.bindings = bindings; this.tasks = tasks; - forks = new HashMap(); + forkedDirectInvocations = new HashMap(); + forkedPhases = new HashMap(); lateBoundMojos = new ArrayList(); directInvocationBindings = new HashMap(); } - private BuildPlan( final LifecycleBindings bindings, final Map forks, final List lateBoundMojos, + private BuildPlan( final LifecycleBindings bindings, final Map forkedDirectInvocations, final Map forkedPhases, final List lateBoundMojos, final Map directInvocationBindings, final List tasks ) { this.bindings = LifecycleUtils.cloneBindings( bindings ); - this.forks = new HashMap( forks ); + this.forkedDirectInvocations = new HashMap( forkedDirectInvocations ); + this.forkedPhases = new HashMap( forkedPhases ); this.lateBoundMojos = new ArrayList( lateBoundMojos ); this.tasks = tasks; this.directInvocationBindings = new HashMap( directInvocationBindings ); @@ -100,23 +104,36 @@ public class BuildPlan return directInvocationBindings; } - public Map getForks() + public Map getForkedDirectInvocations() { - return forks; + return forkedDirectInvocations; + } + + public Map getForkedPhases() + { + return forkedPhases; } public void addForkedExecution( final MojoBinding mojoBinding, final BuildPlan plan ) { String key = MojoBindingUtils.createMojoBindingKey( mojoBinding, false ); - forks.put( key, plan ); + forkedPhases.put( key, plan ); } public void addForkedExecution( final MojoBinding mojoBinding, final List forkedInvocations ) { String key = MojoBindingUtils.createMojoBindingKey( mojoBinding, false ); - forks.put( key, forkedInvocations ); + List invoke = (List) forkedDirectInvocations.get( key ); + + if ( invoke == null ) + { + invoke = new ArrayList(); + forkedDirectInvocations.put( key, invoke ); + } + + invoke.addAll( forkedInvocations ); } public void addLateBoundMojo( final MojoBinding mojoBinding ) @@ -126,12 +143,17 @@ public class BuildPlan public BuildPlan copy( final List newTasks ) { - return new BuildPlan( bindings, forks, lateBoundMojos, directInvocationBindings, newTasks ); + return new BuildPlan( bindings, forkedDirectInvocations, forkedPhases, lateBoundMojos, directInvocationBindings, newTasks ); } public void resetExecutionProgress() { renderedLifecycleMojos = new ArrayList(); + for ( Iterator it = forkedPhases.values().iterator(); it.hasNext(); ) + { + BuildPlan plan = (BuildPlan) it.next(); + plan.resetExecutionProgress(); + } } public List renderExecutionPlan( final Stack executionStack ) @@ -207,69 +229,54 @@ public class BuildPlan 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(); + + BuildPlan forkedPlan = (BuildPlan) forkedPhases.get( key ); + + // if we have a forked build plan, recurse into it and retrieve the execution plan. + if ( forkedPlan != null ) { - List forkedBindings = new ArrayList(); + forkedBindings = forkedPlan.renderExecutionPlan( executionStack ); + } - // if the fork is a build plan, recurse into it and retrieve the execution plan. - if ( fork instanceof BuildPlan ) + List directInvocations = (List) forkedDirectInvocations.get( key ); + + // 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. + if ( directInvocations != null ) + { + for ( Iterator it = directInvocations.iterator(); it.hasNext(); ) { - 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 ) ) { - 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(); - } + continue; } - } - if ( !forkedBindings.isEmpty() ) - { - bindings.add( StateManagementUtils.createStartForkedExecutionMojoBinding() ); - bindings.addAll( forkedBindings ); - bindings.add( StateManagementUtils.createEndForkedExecutionMojoBinding() ); - } - - bindings.add( mojoBinding ); - - if ( !forkedBindings.isEmpty() ) - { - bindings.add( StateManagementUtils.createClearForkedExecutionMojoBinding() ); + addResolverIfLateBound( invocation, forkedBindings ); + forkedBindings.addAll( findForkedBindings( invocation, executionStack ) ); } } - else + + if ( !forkedBindings.isEmpty() ) { - bindings.add( mojoBinding ); + bindings.add( StateManagementUtils.createStartForkedExecutionMojoBinding() ); + bindings.addAll( forkedBindings ); + bindings.add( StateManagementUtils.createEndForkedExecutionMojoBinding() ); + } + + bindings.add( mojoBinding ); + + if ( !forkedBindings.isEmpty() ) + { + bindings.add( StateManagementUtils.createClearForkedExecutionMojoBinding() ); } } finally diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/plan/DefaultBuildPlanner.java b/maven-core/src/main/java/org/apache/maven/lifecycle/plan/DefaultBuildPlanner.java index d7bcb1e5f9..6a8517e6e6 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/plan/DefaultBuildPlanner.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/plan/DefaultBuildPlanner.java @@ -27,9 +27,9 @@ import java.util.Stack; * 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 @@ -78,7 +78,9 @@ public class DefaultBuildPlanner if ( !LifecycleUtils.isValidPhaseName( task ) ) { - MojoBinding binding = mojoBindingFactory.parseMojoBinding( task, project, true ); + logger.warn( "Assuming that mojo: \'" + task + "\' does NOT need configuration from the section of the POM." ); + + MojoBinding binding = mojoBindingFactory.parseMojoBinding( task, project, true, false ); plan.addDirectInvocationBinding( task, binding ); } } @@ -124,7 +126,7 @@ public class DefaultBuildPlanner + pluginDescriptor.getId() + "." ); } - findForkModifiers( mojoBinding, pluginDescriptor, plan, project ); + findForkModifiers( mojoBinding, pluginDescriptor, plan, project, false ); } /** @@ -172,7 +174,7 @@ public class DefaultBuildPlanner if ( pd != null ) { - findForkModifiers( reportBinding, pd, plan, project ); + findForkModifiers( reportBinding, pd, plan, project, true ); } } } @@ -218,7 +220,7 @@ public class DefaultBuildPlanner * forked execution, along with any new mojos/lifecycles that entails. */ private void findForkModifiers( final MojoBinding mojoBinding, final PluginDescriptor pluginDescriptor, - final BuildPlan plan, final MavenProject project ) + final BuildPlan plan, final MavenProject project, final boolean includeReportConfig ) throws LifecyclePlannerException, LifecycleSpecificationException, LifecycleLoaderException { String referencingGoal = mojoBinding.getGoal(); @@ -233,11 +235,11 @@ public class DefaultBuildPlanner if ( mojoDescriptor.getExecuteGoal() != null ) { - recurseSingleMojoFork( mojoBinding, pluginDescriptor, plan, project ); + recurseSingleMojoFork( mojoBinding, pluginDescriptor, plan, project, includeReportConfig ); } else if ( mojoDescriptor.getExecutePhase() != null ) { - recursePhaseMojoFork( mojoBinding, pluginDescriptor, plan, project ); + recursePhaseMojoFork( mojoBinding, pluginDescriptor, plan, project, includeReportConfig ); } } @@ -245,13 +247,14 @@ public class DefaultBuildPlanner * 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)} * method to handle the actual plan modification. */ private void recursePhaseMojoFork( final MojoBinding mojoBinding, final PluginDescriptor pluginDescriptor, - final BuildPlan plan, final MavenProject project ) + final BuildPlan plan, final MavenProject project, + final boolean includeReportConfig ) throws LifecyclePlannerException, LifecycleSpecificationException, LifecycleLoaderException { String referencingGoal = mojoBinding.getGoal(); @@ -279,7 +282,7 @@ public class DefaultBuildPlanner try { overlayBindings = - lifecycleBindingManager.getPluginLifecycleOverlay( pluginDescriptor, executeLifecycle, project ); + lifecycleBindingManager.getPluginLifecycleOverlay( pluginDescriptor, executeLifecycle, project, includeReportConfig ); } catch ( LifecycleLoaderException e ) { @@ -302,7 +305,7 @@ public class DefaultBuildPlanner * method to actually inject the modification. */ private void recurseSingleMojoFork( final MojoBinding mojoBinding, final PluginDescriptor pluginDescriptor, - final BuildPlan plan, final MavenProject project ) + final BuildPlan plan, final MavenProject project, final boolean includeReportConfig ) throws LifecyclePlannerException, LifecycleSpecificationException, LifecycleLoaderException { String referencingGoal = mojoBinding.getGoal(); @@ -325,7 +328,7 @@ public class DefaultBuildPlanner MojoBinding binding = mojoBindingFactory.createMojoBinding( pluginDescriptor.getGroupId(), pluginDescriptor.getArtifactId(), - pluginDescriptor.getVersion(), executeGoal, project ); + pluginDescriptor.getVersion(), executeGoal, project, includeReportConfig ); binding.setOrigin( "Forked from " + referencingGoal ); diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/statemgmt/ResolveLateBoundPluginMojo.java b/maven-core/src/main/java/org/apache/maven/lifecycle/statemgmt/ResolveLateBoundPluginMojo.java index 8f1fd0ccb2..57dac48156 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/statemgmt/ResolveLateBoundPluginMojo.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/statemgmt/ResolveLateBoundPluginMojo.java @@ -28,13 +28,15 @@ public class ResolveLateBoundPluginMojo extends AbstractMojo private String goal; + private boolean includeReportConfig = false; + private MavenProject project; private MojoBindingFactory bindingFactory; public void execute() throws MojoExecutionException, MojoFailureException { - MojoBinding binding = bindingFactory.createMojoBinding( groupId, artifactId, version, artifactId, project ); + MojoBinding binding = bindingFactory.createMojoBinding( groupId, artifactId, version, artifactId, project, includeReportConfig ); try { PluginDescriptor descriptor = pluginLoader.loadPlugin( binding, project ); diff --git a/maven-core/src/main/resources/META-INF/maven/plugin.xml b/maven-core/src/main/resources/META-INF/maven/plugin.xml index 38a88a27d8..7f1fa9a6fd 100644 --- a/maven-core/src/main/resources/META-INF/maven/plugin.xml +++ b/maven-core/src/main/resources/META-INF/maven/plugin.xml @@ -162,6 +162,13 @@ true The mojo's goal that we're looking for, as an extra validation step. + + includeReportConfig + boolean + false + true + Whether the mojo should include plugin-configuration from the reporting section. + @@ -169,6 +176,7 @@ ${artifactId} ${version} ${goal} + false diff --git a/maven-core/src/test/java/org/apache/maven/lifecycle/binding/DefaultMojoBindingFactoryTest.java b/maven-core/src/test/java/org/apache/maven/lifecycle/binding/DefaultMojoBindingFactoryTest.java index 2d08af079a..e8271faf5c 100644 --- a/maven-core/src/test/java/org/apache/maven/lifecycle/binding/DefaultMojoBindingFactoryTest.java +++ b/maven-core/src/test/java/org/apache/maven/lifecycle/binding/DefaultMojoBindingFactoryTest.java @@ -12,11 +12,11 @@ public class DefaultMojoBindingFactoryTest { private MojoBindingFactory factory; - + public void setUp() throws Exception { super.setUp(); - + factory = (MojoBindingFactory) lookup( MojoBindingFactory.ROLE, "default" ); } @@ -27,7 +27,7 @@ public class DefaultMojoBindingFactoryTest try { - factory.parseMojoBinding( spec, new MavenProject( new Model() ), false ); + factory.parseMojoBinding( spec, new MavenProject( new Model() ), false, false ); fail( "Should fail when prefix references are not allowed." ); } @@ -42,7 +42,7 @@ public class DefaultMojoBindingFactoryTest { String spec = "group:artifact:goal"; - MojoBinding binding = factory.parseMojoBinding( spec, new MavenProject( new Model() ), false ); + MojoBinding binding = factory.parseMojoBinding( spec, new MavenProject( new Model() ), false, false ); assertEquals( "group", binding.getGroupId() ); assertEquals( "artifact", binding.getArtifactId() ); @@ -55,7 +55,7 @@ public class DefaultMojoBindingFactoryTest { String spec = "group:artifact:version:goal"; - MojoBinding binding = factory.parseMojoBinding( spec, new MavenProject( new Model() ), false ); + MojoBinding binding = factory.parseMojoBinding( spec, new MavenProject( new Model() ), false, false ); assertEquals( "group", binding.getGroupId() ); assertEquals( "artifact", binding.getArtifactId() ); @@ -70,7 +70,7 @@ public class DefaultMojoBindingFactoryTest try { - factory.parseMojoBinding( spec, new MavenProject( new Model() ), false ); + factory.parseMojoBinding( spec, new MavenProject( new Model() ), false, false ); fail( "Should fail because spec has too many parts (type part is not allowed)." ); }