maven-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Olivier Lamy <ol...@apache.org>
Subject Re: [1/2] git commit: MNG-5549 introduced MojoExecutionListener and ProjectExecutionListener
Date Mon, 16 Dec 2013 10:27:28 GMT
On 16 December 2013 15:11,  <ifedorenko@apache.org> wrote:
> Updated Branches:
>   refs/heads/master 07fecbd9e -> b99658c94
>
>
> MNG-5549 introduced MojoExecutionListener and ProjectExecutionListener
>
> Signed-off-by: Igor Fedorenko <ifedorenko@apache.org>
>
>
> 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 <ifedorenko@apache.org>
> Authored: Sat Dec 14 19:43:42 2013 -0500
> Committer: Igor Fedorenko <ifedorenko@apache.org>
> 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: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org


Mime
View raw message