On 16 December 2013 15:11, <[email protected]> wrote: > Updated Branches: > refs/heads/master 07fecbd9e -> b99658c94 > > > MNG-5549 introduced MojoExecutionListener and ProjectExecutionListener > > Signed-off-by: Igor Fedorenko <[email protected]> > > > Project: http://git-wip-us.apache.org/repos/asf/maven/repo > Commit: http://git-wip-us.apache.org/repos/asf/maven/commit/bc84e6c7 > Tree: http://git-wip-us.apache.org/repos/asf/maven/tree/bc84e6c7 > Diff: http://git-wip-us.apache.org/repos/asf/maven/diff/bc84e6c7 > > Branch: refs/heads/master > Commit: bc84e6c7d307f119d82d5ae8082cc5e4f7eb7996 > Parents: 07fecbd > Author: Igor Fedorenko <[email protected]> > Authored: Sat Dec 14 19:43:42 2013 -0500 > Committer: Igor Fedorenko <[email protected]> > Committed: Sat Dec 14 19:43:42 2013 -0500 > > ---------------------------------------------------------------------- > .../maven/execution/MojoExecutionListener.java | 46 +++++++ > .../execution/ProjectExecutionListener.java | 49 +++++++ > .../execution/scope/MojoExecutionListener.java | 48 ------- > .../scope/WeakMojoExecutionListener.java | 50 ++++++++ > .../scope/internal/MojoExecutionScope.java | 36 ++++-- > .../CompoundProjectExecutionListener.java | 76 +++++++++++ > .../internal/LifecycleModuleBuilder.java | 34 ++++- > .../plugin/CompoundMojoExecutionListener.java | 67 ++++++++++ > .../maven/plugin/DefaultBuildPluginManager.java | 33 ++++- > .../DelegatingMojoExecutionListener.java | 61 +++++++++ > .../DelegatingProjectExecutionListener.java | 66 ++++++++++ > .../maven/lifecycle/LifecycleExecutorTest.java | 127 +++++++++++++++++++ > 12 files changed, 626 insertions(+), 67 deletions(-) > ---------------------------------------------------------------------- > > > http://git-wip-us.apache.org/repos/asf/maven/blob/bc84e6c7/maven-core/src/main/java/org/apache/maven/execution/MojoExecutionListener.java > ---------------------------------------------------------------------- > diff --git > a/maven-core/src/main/java/org/apache/maven/execution/MojoExecutionListener.java > > b/maven-core/src/main/java/org/apache/maven/execution/MojoExecutionListener.java > new file mode 100644 > index 0000000..6b824eb > --- /dev/null > +++ > b/maven-core/src/main/java/org/apache/maven/execution/MojoExecutionListener.java > @@ -0,0 +1,46 @@ > +package org.apache.maven.execution; > + > +/* > + * 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. > + */ > + > +import org.apache.maven.execution.scope.WeakMojoExecutionListener; > +import org.apache.maven.plugin.Mojo; > +import org.apache.maven.plugin.MojoExecution; > +import org.apache.maven.plugin.MojoExecutionException; > +import org.apache.maven.project.MavenProject; > + > +/** > + * Extension point that allows build extensions observe and possibly veto > mojo executions. > + * > + * @see WeakMojoExecutionListener > + * @since 3.1.2 > + * @provisional This interface is part of work in progress and can be > changed or removed without notice. > + */ > +public interface MojoExecutionListener > +{ > + public void beforeMojoExecution( MavenSession session, MavenProject > project, MojoExecution execution, Mojo mojo ) > + throws MojoExecutionException; > + > + public void afterMojoExecutionSuccess( MavenSession session, > MavenProject project, MojoExecution execution, > + Mojo mojo ) > + throws MojoExecutionException; > + > + public void afterExecutionFailure( MavenSession session, MavenProject > project, MojoExecution execution, Mojo mojo, > + Throwable cause ); > +}
I wonder if it will be easier for future enhancement to use a bean with fields for those objects. MojoExecutionListenerEvent with getMavenSession() etc... Maybe will be simpler to add getter to this bean than changing the signature of the interface. ? > > http://git-wip-us.apache.org/repos/asf/maven/blob/bc84e6c7/maven-core/src/main/java/org/apache/maven/execution/ProjectExecutionListener.java > ---------------------------------------------------------------------- > diff --git > a/maven-core/src/main/java/org/apache/maven/execution/ProjectExecutionListener.java > > b/maven-core/src/main/java/org/apache/maven/execution/ProjectExecutionListener.java > new file mode 100644 > index 0000000..d3d9739 > --- /dev/null > +++ > b/maven-core/src/main/java/org/apache/maven/execution/ProjectExecutionListener.java > @@ -0,0 +1,49 @@ > +package org.apache.maven.execution; > + > +/* > + * 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. > + */ > + > +import java.util.List; > + > +import org.apache.maven.lifecycle.LifecycleExecutionException; > +import org.apache.maven.plugin.MojoExecution; > +import org.apache.maven.project.MavenProject; > + > +/** > + * Extension point that allows build extensions observe and possibly veto > project build execution. > + * > + * @see ExecutionListener > + * @see MojoExecutionListener > + * @since 3.1.2 > + * @provisional This interface is part of work in progress and can be > changed or removed without notice. > + */ > +public interface ProjectExecutionListener > +{ > + public void beforeProjectExecution( MavenSession session, MavenProject > project ) > + throws LifecycleExecutionException; > + > + public void beforeProjectLifecycleExecution( MavenSession session, > MavenProject project, > + List<MojoExecution> > executionPlan ) > + throws LifecycleExecutionException; > + > + public void afterProjectExecutionSuccess( MavenSession session, > MavenProject project ) > + throws LifecycleExecutionException; > + > + public void afterProjectExecutionFailure( MavenSession session, > MavenProject project, Throwable cause ); > +} > > http://git-wip-us.apache.org/repos/asf/maven/blob/bc84e6c7/maven-core/src/main/java/org/apache/maven/execution/scope/MojoExecutionListener.java > ---------------------------------------------------------------------- > diff --git > a/maven-core/src/main/java/org/apache/maven/execution/scope/MojoExecutionListener.java > > b/maven-core/src/main/java/org/apache/maven/execution/scope/MojoExecutionListener.java > deleted file mode 100644 > index 7a9c84b..0000000 > --- > a/maven-core/src/main/java/org/apache/maven/execution/scope/MojoExecutionListener.java > +++ /dev/null > @@ -1,48 +0,0 @@ > -package org.apache.maven.execution.scope; > - > -/* > - * 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. > - */ > - > -import org.apache.maven.plugin.MojoExecutionException; > - > -/** > - * Helper interface that allows mojo execution scoped components to be > notified before execution start and after > - * execution completion. The main purpose of this interface is to allow mojo > execution scoped components perform setup > - * before and cleanup after mojo execution. > - * <p> > - * TODO decide if Mojo should be passed as parameter of callback methods > - * > - * @author igor > - * @since 3.1.2 > - * @provisional This interface is part of work in progress and can be > changed or removed without notice. > - */ > -public interface MojoExecutionListener > -{ > - // TODO decide if this is needed > - // public void beforeExecution() throws MojoExecutionException; > - > - public void afterMojoExecutionSuccess() > - throws MojoExecutionException; > - > - // TODO decide if this is needed. > - // public void afterExecutionFailure(Throwable t) throws > MojoExecutionException; > - > - public void afterMojoExecutionAlways() > - throws MojoExecutionException; > -} > > http://git-wip-us.apache.org/repos/asf/maven/blob/bc84e6c7/maven-core/src/main/java/org/apache/maven/execution/scope/WeakMojoExecutionListener.java > ---------------------------------------------------------------------- > diff --git > a/maven-core/src/main/java/org/apache/maven/execution/scope/WeakMojoExecutionListener.java > > b/maven-core/src/main/java/org/apache/maven/execution/scope/WeakMojoExecutionListener.java > new file mode 100644 > index 0000000..5537106 > --- /dev/null > +++ > b/maven-core/src/main/java/org/apache/maven/execution/scope/WeakMojoExecutionListener.java > @@ -0,0 +1,50 @@ > +package org.apache.maven.execution.scope; > + > +/* > + * 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. > + */ > + > +import org.apache.maven.execution.MavenSession; > +import org.apache.maven.execution.MojoExecutionListener; > +import org.apache.maven.plugin.Mojo; > +import org.apache.maven.plugin.MojoExecution; > +import org.apache.maven.plugin.MojoExecutionException; > +import org.apache.maven.project.MavenProject; > + > +/** > + * Extension point that allows build extensions observe and possibly veto > mojo executions. > + * <p> > + * Unlike {@link MojoExecutionListener}, this extension point does not > trigger instantiation of the component, hence > + * "weak" class name prefix. Only applies to mojo execution scoped > components. > + * > + * @see MojoExecutionListener > + * @since 3.1.2 > + * @provisional This interface is part of work in progress and can be > changed or removed without notice. > + */ > +public interface WeakMojoExecutionListener > +{ > + public void beforeMojoExecution( MavenSession session, MavenProject > project, MojoExecution execution, Mojo mojo ) > + throws MojoExecutionException; > + > + public void afterMojoExecutionSuccess( MavenSession session, > MavenProject project, MojoExecution execution, > + Mojo mojo ) > + throws MojoExecutionException; > + > + public void afterExecutionFailure( MavenSession session, MavenProject > project, MojoExecution execution, Mojo mojo, > + Throwable cause ); > +} > > http://git-wip-us.apache.org/repos/asf/maven/blob/bc84e6c7/maven-core/src/main/java/org/apache/maven/execution/scope/internal/MojoExecutionScope.java > ---------------------------------------------------------------------- > diff --git > a/maven-core/src/main/java/org/apache/maven/execution/scope/internal/MojoExecutionScope.java > > b/maven-core/src/main/java/org/apache/maven/execution/scope/internal/MojoExecutionScope.java > index ce169e1..80badfc 100644 > --- > a/maven-core/src/main/java/org/apache/maven/execution/scope/internal/MojoExecutionScope.java > +++ > b/maven-core/src/main/java/org/apache/maven/execution/scope/internal/MojoExecutionScope.java > @@ -26,8 +26,10 @@ import javax.inject.Named; > import javax.inject.Singleton; > > import org.apache.maven.execution.MavenSession; > -import org.apache.maven.execution.scope.MojoExecutionListener; > +import org.apache.maven.execution.MojoExecutionListener; > import org.apache.maven.execution.scope.MojoExecutionScoped; > +import org.apache.maven.execution.scope.WeakMojoExecutionListener; > +import org.apache.maven.plugin.Mojo; > import org.apache.maven.plugin.MojoExecution; > import org.apache.maven.plugin.MojoExecutionException; > import org.apache.maven.project.MavenProject; > @@ -46,7 +48,7 @@ import com.google.inject.util.Providers; > @Named > @Singleton > public class MojoExecutionScope > - implements Scope > + implements Scope, MojoExecutionListener > { > private static final Provider<Object> SEEDED_KEY_PROVIDER = new > Provider<Object>() > { > @@ -138,7 +140,7 @@ public class MojoExecutionScope > } > > T provided = (T) state.provided.get( key ); > - if ( provided == null ) > + if ( provided == null && unscoped != null ) > { > provided = unscoped.get(); > state.provided.put( key, provided ); > @@ -174,28 +176,40 @@ public class MojoExecutionScope > }; > } > > - public void afterExecutionSuccess() > + public void beforeMojoExecution( MavenSession session, MavenProject > project, MojoExecution execution, Mojo mojo ) > throws MojoExecutionException > { > for ( Object provided : getScopeState().provided.values() ) > { > - if ( provided instanceof MojoExecutionListener ) > + if ( provided instanceof WeakMojoExecutionListener ) > { > - ( (MojoExecutionListener) provided > ).afterMojoExecutionSuccess(); > - // TODO maybe deal with multiple MojoExecutionExceptions > + ( (WeakMojoExecutionListener) provided > ).beforeMojoExecution( session, project, execution, mojo ); > } > } > } > > - public void afterExecutionAlways() > + public void afterMojoExecutionSuccess( MavenSession session, > MavenProject project, MojoExecution execution, > + Mojo mojo ) > throws MojoExecutionException > { > for ( Object provided : getScopeState().provided.values() ) > { > - if ( provided instanceof MojoExecutionListener ) > + if ( provided instanceof WeakMojoExecutionListener ) > { > - ( (MojoExecutionListener) provided > ).afterMojoExecutionAlways(); > - // TODO maybe deal with multiple MojoExecutionExceptions > + ( (WeakMojoExecutionListener) provided > ).afterMojoExecutionSuccess( session, project, execution, mojo ); > + } > + } > + } > + > + public void afterExecutionFailure( MavenSession session, MavenProject > project, MojoExecution execution, Mojo mojo, > + Throwable cause ) > + { > + for ( Object provided : getScopeState().provided.values() ) > + { > + if ( provided instanceof WeakMojoExecutionListener ) > + { > + ( (WeakMojoExecutionListener) provided > ).afterExecutionFailure( session, project, execution, mojo, > + > cause ); > } > } > } > > http://git-wip-us.apache.org/repos/asf/maven/blob/bc84e6c7/maven-core/src/main/java/org/apache/maven/lifecycle/internal/CompoundProjectExecutionListener.java > ---------------------------------------------------------------------- > diff --git > a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/CompoundProjectExecutionListener.java > > b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/CompoundProjectExecutionListener.java > new file mode 100644 > index 0000000..8bdd210 > --- /dev/null > +++ > b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/CompoundProjectExecutionListener.java > @@ -0,0 +1,76 @@ > +package org.apache.maven.lifecycle.internal; > + > +/* > + * 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. > + */ > + > +import java.util.Collection; > +import java.util.List; > + > +import org.apache.maven.execution.MavenSession; > +import org.apache.maven.execution.ProjectExecutionListener; > +import org.apache.maven.lifecycle.LifecycleExecutionException; > +import org.apache.maven.plugin.MojoExecution; > +import org.apache.maven.project.MavenProject; > + > +class CompoundProjectExecutionListener > + implements ProjectExecutionListener > +{ > + private final Collection<ProjectExecutionListener> listeners; > + > + public CompoundProjectExecutionListener( > Collection<ProjectExecutionListener> listeners ) > + { > + this.listeners = listeners; // NB this is live injected collection > + } > + > + public void beforeProjectExecution( MavenSession session, MavenProject > project ) > + throws LifecycleExecutionException > + { > + for ( ProjectExecutionListener listener : listeners ) > + { > + listener.beforeProjectExecution( session, project ); > + } > + } > + > + public void beforeProjectLifecycleExecution( MavenSession session, > MavenProject project, > + List<MojoExecution> > executionPlan ) > + throws LifecycleExecutionException > + { > + for ( ProjectExecutionListener listener : listeners ) > + { > + listener.beforeProjectLifecycleExecution( session, project, > executionPlan ); > + } > + } > + > + public void afterProjectExecutionSuccess( MavenSession session, > MavenProject project ) > + throws LifecycleExecutionException > + { > + for ( ProjectExecutionListener listener : listeners ) > + { > + listener.afterProjectExecutionSuccess( session, project ); > + } > + } > + > + public void afterProjectExecutionFailure( MavenSession session, > MavenProject project, Throwable cause ) > + { > + for ( ProjectExecutionListener listener : listeners ) > + { > + listener.afterProjectExecutionFailure( session, project, cause ); > + } > + } > +} > > http://git-wip-us.apache.org/repos/asf/maven/blob/bc84e6c7/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleModuleBuilder.java > ---------------------------------------------------------------------- > diff --git > a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleModuleBuilder.java > > b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleModuleBuilder.java > index c8a3cf4..95f1c19 100644 > --- > a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleModuleBuilder.java > +++ > b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleModuleBuilder.java > @@ -19,20 +19,23 @@ package org.apache.maven.lifecycle.internal; > * under the License. > */ > > +import java.util.HashSet; > +import java.util.List; > + > import org.apache.maven.artifact.Artifact; > import org.apache.maven.execution.BuildSuccess; > import org.apache.maven.execution.ExecutionEvent; > import org.apache.maven.execution.MavenSession; > +import org.apache.maven.execution.ProjectExecutionListener; > import org.apache.maven.lifecycle.MavenExecutionPlan; > +import org.apache.maven.plugin.MojoExecution; > import org.apache.maven.project.MavenProject; > import org.codehaus.plexus.component.annotations.Component; > import org.codehaus.plexus.component.annotations.Requirement; > > -import java.util.HashSet; > - > /** > * Builds one or more lifecycles for a full module > - * > + * > * @since 3.0 > * @author Benjamin Bentmann > * @author Jason van Zyl > @@ -53,6 +56,18 @@ public class LifecycleModuleBuilder > @Requirement > private ExecutionEventCatapult eventCatapult; > > + private ProjectExecutionListener projectExecutionListener; > + > + // this tricks plexus-component-metadata generate required metadata > + @Requirement > + private List<ProjectExecutionListener> projectExecutionListeners; > + > + public void setProjectExecutionListeners( final > List<ProjectExecutionListener> listeners ) > + { > + this.projectExecutionListeners = listeners; > + this.projectExecutionListener = new > CompoundProjectExecutionListener( listeners ); > + } > + > public void buildProject( MavenSession session, ReactorContext > reactorContext, MavenProject currentProject, > TaskSegment taskSegment ) > { > @@ -75,16 +90,23 @@ public class LifecycleModuleBuilder > return; > } > > + BuilderCommon.attachToThread( currentProject ); > + > + projectExecutionListener.beforeProjectExecution( rootSession, > currentProject ); > + > eventCatapult.fire( ExecutionEvent.Type.ProjectStarted, session, > null ); > > - BuilderCommon.attachToThread( currentProject ); > MavenExecutionPlan executionPlan = > builderCommon.resolveBuildPlan( session, currentProject, > taskSegment, new HashSet<Artifact>() ); > + List<MojoExecution> mojoExecutions = > executionPlan.getMojoExecutions(); > > - mojoExecutor.execute( session, > executionPlan.getMojoExecutions(), reactorContext.getProjectIndex() ); > + projectExecutionListener.beforeProjectLifecycleExecution( > rootSession, currentProject, mojoExecutions ); > + mojoExecutor.execute( session, mojoExecutions, > reactorContext.getProjectIndex() ); > > long buildEndTime = System.currentTimeMillis(); > > + projectExecutionListener.afterProjectExecutionSuccess( > rootSession, currentProject ); > + > reactorContext.getResult().addBuildSummary( > new BuildSuccess( currentProject, buildEndTime - > buildStartTime ) ); > > @@ -93,6 +115,8 @@ public class LifecycleModuleBuilder > catch ( Exception e ) > { > builderCommon.handleBuildError( reactorContext, rootSession, > session, currentProject, e, buildStartTime ); > + > + projectExecutionListener.afterProjectExecutionFailure( session, > currentProject, e ); > } > finally > { > > http://git-wip-us.apache.org/repos/asf/maven/blob/bc84e6c7/maven-core/src/main/java/org/apache/maven/plugin/CompoundMojoExecutionListener.java > ---------------------------------------------------------------------- > diff --git > a/maven-core/src/main/java/org/apache/maven/plugin/CompoundMojoExecutionListener.java > > b/maven-core/src/main/java/org/apache/maven/plugin/CompoundMojoExecutionListener.java > new file mode 100644 > index 0000000..7b5ff66 > --- /dev/null > +++ > b/maven-core/src/main/java/org/apache/maven/plugin/CompoundMojoExecutionListener.java > @@ -0,0 +1,67 @@ > +package org.apache.maven.plugin; > + > +/* > + * 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. > + */ > + > +import java.util.Collection; > + > +import org.apache.maven.execution.MavenSession; > +import org.apache.maven.execution.MojoExecutionListener; > +import org.apache.maven.project.MavenProject; > + > +class CompoundMojoExecutionListener > + implements MojoExecutionListener > +{ > + > + private final Collection<MojoExecutionListener> listeners; > + > + public CompoundMojoExecutionListener( Collection<MojoExecutionListener> > listeners ) > + { > + this.listeners = listeners; // NB this is live injected collection > + } > + > + public void beforeMojoExecution( MavenSession session, MavenProject > project, MojoExecution execution, Mojo mojo ) > + throws MojoExecutionException > + { > + for ( MojoExecutionListener listener : listeners ) > + { > + listener.beforeMojoExecution( session, project, execution, mojo > ); > + } > + } > + > + public void afterMojoExecutionSuccess( MavenSession session, > MavenProject project, MojoExecution execution, > + Mojo mojo ) > + throws MojoExecutionException > + { > + for ( MojoExecutionListener listener : listeners ) > + { > + listener.afterMojoExecutionSuccess( session, project, execution, > mojo ); > + } > + } > + > + public void afterExecutionFailure( MavenSession session, MavenProject > project, MojoExecution execution, Mojo mojo, > + Throwable cause ) > + { > + for ( MojoExecutionListener listener : listeners ) > + { > + listener.afterExecutionFailure( session, project, execution, > mojo, cause ); > + } > + } > + > +} > > http://git-wip-us.apache.org/repos/asf/maven/blob/bc84e6c7/maven-core/src/main/java/org/apache/maven/plugin/DefaultBuildPluginManager.java > ---------------------------------------------------------------------- > diff --git > a/maven-core/src/main/java/org/apache/maven/plugin/DefaultBuildPluginManager.java > > b/maven-core/src/main/java/org/apache/maven/plugin/DefaultBuildPluginManager.java > index 949a228..5a10053 100644 > --- > a/maven-core/src/main/java/org/apache/maven/plugin/DefaultBuildPluginManager.java > +++ > b/maven-core/src/main/java/org/apache/maven/plugin/DefaultBuildPluginManager.java > @@ -24,6 +24,7 @@ import java.io.PrintStream; > import java.util.List; > > import org.apache.maven.execution.MavenSession; > +import org.apache.maven.execution.MojoExecutionListener; > import org.apache.maven.execution.scope.internal.MojoExecutionScope; > import org.apache.maven.model.Plugin; > import org.apache.maven.plugin.descriptor.MojoDescriptor; > @@ -52,6 +53,18 @@ public class DefaultBuildPluginManager > @Requirement > private MojoExecutionScope scope; > > + private MojoExecutionListener mojoExecutionListener; > + > + // this tricks plexus-component-metadata generate required metadata > + @Requirement( role = MojoExecutionListener.class ) > + private List<MojoExecutionListener> mojoExecutionListeners; > + > + public void setMojoExecutionListeners( final List<MojoExecutionListener> > listeners ) > + { > + this.mojoExecutionListeners = listeners; > + this.mojoExecutionListener = new CompoundMojoExecutionListener( > listeners ); > + } > + > /** > * @param plugin > * @param repositories > @@ -112,9 +125,11 @@ public class DefaultBuildPluginManager > // MavenProjectHelper.attachArtifact(..). > try > { > + mojoExecutionListener.beforeMojoExecution( oldSession, > project, mojoExecution, mojo ); > + > mojo.execute(); > > - scope.afterExecutionSuccess(); > + mojoExecutionListener.afterMojoExecutionSuccess( oldSession, > project, mojoExecution, mojo ); > } > catch ( ClassCastException e ) > { > @@ -128,10 +143,14 @@ public class DefaultBuildPluginManager > } > catch ( PluginContainerException e ) > { > + mojoExecutionListener.afterExecutionFailure( oldSession, > project, mojoExecution, mojo, e ); > + > throw new PluginExecutionException( mojoExecution, project, e ); > } > catch ( NoClassDefFoundError e ) > { > + mojoExecutionListener.afterExecutionFailure( oldSession, > project, mojoExecution, mojo, e ); > + > ByteArrayOutputStream os = new ByteArrayOutputStream( 1024 ); > PrintStream ps = new PrintStream( os ); > ps.println( "A required class was missing while executing " + > mojoDescriptor.getId() + ": " > @@ -144,6 +163,8 @@ public class DefaultBuildPluginManager > } > catch ( LinkageError e ) > { > + mojoExecutionListener.afterExecutionFailure( oldSession, > project, mojoExecution, mojo, e ); > + > ByteArrayOutputStream os = new ByteArrayOutputStream( 1024 ); > PrintStream ps = new PrintStream( os ); > ps.println( "An API incompatibility was encountered while > executing " + mojoDescriptor.getId() + ": " > @@ -156,6 +177,8 @@ public class DefaultBuildPluginManager > } > catch ( ClassCastException e ) > { > + mojoExecutionListener.afterExecutionFailure( oldSession, > project, mojoExecution, mojo, e ); > + > ByteArrayOutputStream os = new ByteArrayOutputStream( 1024 ); > PrintStream ps = new PrintStream( os ); > ps.println( "A type incompatibility occured while executing " + > mojoDescriptor.getId() + ": " > @@ -164,10 +187,14 @@ public class DefaultBuildPluginManager > > throw new PluginExecutionException( mojoExecution, project, > os.toString(), e ); > } > - finally > + catch ( RuntimeException e ) > { > - scope.afterExecutionAlways(); > + mojoExecutionListener.afterExecutionFailure( oldSession, > project, mojoExecution, mojo, e ); > > + throw e; > + } > + finally > + { > mavenPluginManager.releaseMojo( mojo, mojoExecution ); > > scope.exit(); > > http://git-wip-us.apache.org/repos/asf/maven/blob/bc84e6c7/maven-core/src/test/java/org/apache/maven/lifecycle/DelegatingMojoExecutionListener.java > ---------------------------------------------------------------------- > diff --git > a/maven-core/src/test/java/org/apache/maven/lifecycle/DelegatingMojoExecutionListener.java > > b/maven-core/src/test/java/org/apache/maven/lifecycle/DelegatingMojoExecutionListener.java > new file mode 100644 > index 0000000..d58329c > --- /dev/null > +++ > b/maven-core/src/test/java/org/apache/maven/lifecycle/DelegatingMojoExecutionListener.java > @@ -0,0 +1,61 @@ > +package org.apache.maven.lifecycle; > + > +import java.util.List; > +import java.util.concurrent.CopyOnWriteArrayList; > + > +import javax.inject.Named; > +import javax.inject.Singleton; > + > +import org.apache.maven.execution.MavenSession; > +import org.apache.maven.execution.MojoExecutionListener; > +import org.apache.maven.plugin.Mojo; > +import org.apache.maven.plugin.MojoExecution; > +import org.apache.maven.plugin.MojoExecutionException; > +import org.apache.maven.project.MavenProject; > + > +@Named > +@Singleton > +public class DelegatingMojoExecutionListener > + implements MojoExecutionListener > +{ > + private final List<MojoExecutionListener> listeners = new > CopyOnWriteArrayList<MojoExecutionListener>(); > + > + public void beforeMojoExecution( MavenSession session, MavenProject > project, MojoExecution execution, Mojo mojo ) > + throws MojoExecutionException > + { > + for ( MojoExecutionListener listener : listeners ) > + { > + listener.beforeMojoExecution( session, project, execution, mojo > ); > + } > + } > + > + public void afterMojoExecutionSuccess( MavenSession session, > MavenProject project, MojoExecution execution, > + Mojo mojo ) > + throws MojoExecutionException > + { > + for ( MojoExecutionListener listener : listeners ) > + { > + listener.afterMojoExecutionSuccess( session, project, execution, > mojo ); > + } > + } > + > + public void afterExecutionFailure( MavenSession session, MavenProject > project, MojoExecution execution, Mojo mojo, > + Throwable cause ) > + { > + for ( MojoExecutionListener listener : listeners ) > + { > + listener.afterExecutionFailure( session, project, execution, > mojo, cause ); > + } > + } > + > + public void addMojoExecutionListener( MojoExecutionListener listener ) > + { > + this.listeners.add( listener ); > + } > + > + public void removeMojoExecutionListener( MojoExecutionListener listener ) > + { > + this.listeners.remove( listener ); > + } > + > +} > > http://git-wip-us.apache.org/repos/asf/maven/blob/bc84e6c7/maven-core/src/test/java/org/apache/maven/lifecycle/DelegatingProjectExecutionListener.java > ---------------------------------------------------------------------- > diff --git > a/maven-core/src/test/java/org/apache/maven/lifecycle/DelegatingProjectExecutionListener.java > > b/maven-core/src/test/java/org/apache/maven/lifecycle/DelegatingProjectExecutionListener.java > new file mode 100644 > index 0000000..27b53c6 > --- /dev/null > +++ > b/maven-core/src/test/java/org/apache/maven/lifecycle/DelegatingProjectExecutionListener.java > @@ -0,0 +1,66 @@ > +package org.apache.maven.lifecycle; > + > +import java.util.List; > +import java.util.concurrent.CopyOnWriteArrayList; > + > +import javax.inject.Named; > +import javax.inject.Singleton; > + > +import org.apache.maven.execution.MavenSession; > +import org.apache.maven.execution.ProjectExecutionListener; > +import org.apache.maven.plugin.MojoExecution; > +import org.apache.maven.project.MavenProject; > + > +@Named > +@Singleton > +public class DelegatingProjectExecutionListener > + implements ProjectExecutionListener > +{ > + private final List<ProjectExecutionListener> listeners = new > CopyOnWriteArrayList<ProjectExecutionListener>(); > + > + public void beforeProjectExecution( MavenSession session, MavenProject > project ) > + throws LifecycleExecutionException > + { > + for ( ProjectExecutionListener listener : listeners ) > + { > + listener.beforeProjectExecution( session, project ); > + } > + } > + > + public void beforeProjectLifecycleExecution( MavenSession session, > MavenProject project, > + List<MojoExecution> > executionPlan ) > + throws LifecycleExecutionException > + { > + for ( ProjectExecutionListener listener : listeners ) > + { > + listener.beforeProjectLifecycleExecution( session, project, > executionPlan ); > + } > + } > + > + public void afterProjectExecutionSuccess( MavenSession session, > MavenProject project ) > + throws LifecycleExecutionException > + { > + for ( ProjectExecutionListener listener : listeners ) > + { > + listener.afterProjectExecutionSuccess( session, project ); > + } > + } > + > + public void afterProjectExecutionFailure( MavenSession session, > MavenProject project, Throwable cause ) > + { > + for ( ProjectExecutionListener listener : listeners ) > + { > + listener.afterProjectExecutionFailure( session, project, cause ); > + } > + } > + > + public void addProjectExecutionListener( ProjectExecutionListener > listener ) > + { > + this.listeners.add( listener ); > + } > + > + public void removeProjectExecutionListener( ProjectExecutionListener > listener ) > + { > + this.listeners.remove( listener ); > + } > +} > > http://git-wip-us.apache.org/repos/asf/maven/blob/bc84e6c7/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorTest.java > ---------------------------------------------------------------------- > diff --git > a/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorTest.java > > b/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorTest.java > index 82e7e93..b983e55 100644 > --- > a/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorTest.java > +++ > b/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorTest.java > @@ -18,11 +18,15 @@ package org.apache.maven.lifecycle; > import java.io.File; > import java.util.ArrayList; > import java.util.Arrays; > +import java.util.Collections; > import java.util.List; > > import org.apache.maven.AbstractCoreMavenComponentTestCase; > import org.apache.maven.exception.ExceptionHandler; > import org.apache.maven.execution.MavenSession; > +import org.apache.maven.execution.MojoExecutionListener; > +import org.apache.maven.execution.ProjectDependencyGraph; > +import org.apache.maven.execution.ProjectExecutionListener; > import > org.apache.maven.lifecycle.internal.DefaultLifecycleTaskSegmentCalculator; > import org.apache.maven.lifecycle.internal.ExecutionPlanItem; > import org.apache.maven.lifecycle.internal.LifecycleExecutionPlanCalculator; > @@ -31,9 +35,12 @@ import > org.apache.maven.lifecycle.internal.LifecycleTaskSegmentCalculator; > import org.apache.maven.lifecycle.internal.MojoDescriptorCreator; > import org.apache.maven.lifecycle.internal.TaskSegment; > import org.apache.maven.model.Plugin; > +import org.apache.maven.plugin.Mojo; > import org.apache.maven.plugin.MojoExecution; > +import org.apache.maven.plugin.MojoExecutionException; > import org.apache.maven.plugin.MojoNotFoundException; > import org.apache.maven.plugin.descriptor.MojoDescriptor; > +import org.apache.maven.project.MavenProject; > import org.codehaus.plexus.component.annotations.Requirement; > import org.codehaus.plexus.util.xml.Xpp3Dom; > > @@ -380,4 +387,124 @@ public class LifecycleExecutorTest > assertEquals("1.0", execution.getConfiguration().getChild( "version" > ).getAttribute( "default-value" )); > } > > + public void testExecutionListeners() > + throws Exception > + { > + final File pom = getProject( "project-basic" ); > + final MavenSession session = createMavenSession( pom ); > + session.setProjectDependencyGraph( new ProjectDependencyGraph() > + { > + public List<MavenProject> getUpstreamProjects( MavenProject > project, boolean transitive ) > + { > + return Collections.emptyList(); > + } > + > + public List<MavenProject> getSortedProjects() > + { > + return Collections.singletonList( > session.getCurrentProject() ); > + } > + > + public List<MavenProject> getDownstreamProjects( MavenProject > project, boolean transitive ) > + { > + return Collections.emptyList(); > + } > + } ); > + > + final List<String> log = new ArrayList<String>(); > + > + MojoExecutionListener mojoListener = new MojoExecutionListener() > + { > + public void beforeMojoExecution( MavenSession session, > MavenProject project, MojoExecution execution, > + Mojo mojo ) > + throws MojoExecutionException > + { > + log.add( "beforeMojoExecution " + project.getArtifactId() + > ":" + execution.getExecutionId() ); > + } > + > + public void afterMojoExecutionSuccess( MavenSession session, > MavenProject project, MojoExecution execution, > + Mojo mojo ) > + throws MojoExecutionException > + { > + log.add( "afterMojoExecutionSuccess " + > project.getArtifactId() + ":" + execution.getExecutionId() ); > + } > + > + public void afterExecutionFailure( MavenSession session, > MavenProject project, MojoExecution execution, > + Mojo mojo, Throwable cause ) > + { > + log.add( "afterExecutionFailure " + project.getArtifactId() > + ":" + execution.getExecutionId() ); > + } > + }; > + ProjectExecutionListener projectListener = new > ProjectExecutionListener() > + { > + public void beforeProjectExecution( MavenSession session, > MavenProject project ) > + throws LifecycleExecutionException > + { > + log.add( "beforeProjectExecution " + project.getArtifactId() > ); > + } > + > + public void beforeProjectLifecycleExecution( MavenSession > session, MavenProject project, > + List<MojoExecution> > executionPlan ) > + throws LifecycleExecutionException > + { > + log.add( "beforeProjectLifecycleExecution " + > project.getArtifactId() ); > + } > + > + public void afterProjectExecutionSuccess( MavenSession session, > MavenProject project ) > + throws LifecycleExecutionException > + { > + log.add( "afterProjectExecutionSuccess " + > project.getArtifactId() ); > + } > + > + public void afterProjectExecutionFailure( MavenSession session, > MavenProject project, Throwable cause ) > + { > + log.add( "afterProjectExecutionFailure " + > project.getArtifactId() ); > + } > + }; > + lookup( DelegatingProjectExecutionListener.class > ).addProjectExecutionListener( projectListener ); > + lookup( DelegatingMojoExecutionListener.class > ).addMojoExecutionListener( mojoListener ); > + > + try > + { > + lifecycleExecutor.execute( session ); > + } > + finally > + { > + lookup( DelegatingProjectExecutionListener.class > ).removeProjectExecutionListener( projectListener ); > + lookup( DelegatingMojoExecutionListener.class > ).removeMojoExecutionListener( mojoListener ); > + } > + > + List<String> expectedLog = Arrays.asList( "beforeProjectExecution > project-basic", // > + > "beforeProjectLifecycleExecution project-basic", // > + "beforeMojoExecution > project-basic:default-resources", // > + "afterMojoExecutionSuccess > project-basic:default-resources", // > + "beforeMojoExecution > project-basic:default-compile", // > + "afterMojoExecutionSuccess > project-basic:default-compile", // > + "beforeMojoExecution > project-basic:default-testResources", // > + "afterMojoExecutionSuccess > project-basic:default-testResources", // > + "beforeMojoExecution > project-basic:default-testCompile", // > + "afterMojoExecutionSuccess > project-basic:default-testCompile", // > + "beforeMojoExecution > project-basic:default-test", // > + "afterMojoExecutionSuccess > project-basic:default-test", // > + "beforeMojoExecution > project-basic:default-jar", // > + "afterMojoExecutionSuccess > project-basic:default-jar", // > + > "afterProjectExecutionSuccess project-basic" // > + ); > + > + assertEventLog( expectedLog, log ); > + } > + > + private static void assertEventLog( List<String> expectedList, > List<String> actualList ) > + { > + assertEquals( toString( expectedList ), toString( actualList ) ); > + } > + > + private static String toString( List<String> lines ) > + { > + StringBuilder sb = new StringBuilder(); > + for ( String line : lines ) > + { > + sb.append( line ).append( '\n' ); > + } > + return sb.toString(); > + } > } > -- Olivier Lamy Ecetera: http://ecetera.com.au http://twitter.com/olamy | http://linkedin.com/in/olamy --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
