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 fc8b1e6129..d8a5f6c9d8 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 @@ -19,6 +19,8 @@ * under the License. */ +import java.util.Collection; +import java.util.IdentityHashMap; import java.util.LinkedList; import java.util.Map; @@ -177,36 +179,42 @@ protected void configure() public void beforeMojoExecution( MojoExecutionEvent event ) throws MojoExecutionException { - for ( Object provided : getScopeState().provided.values() ) + for ( WeakMojoExecutionListener provided : getProvidedListeners() ) { - if ( provided instanceof WeakMojoExecutionListener ) - { - ( (WeakMojoExecutionListener) provided ).beforeMojoExecution( event ); - } + provided.beforeMojoExecution( event ); } } public void afterMojoExecutionSuccess( MojoExecutionEvent event ) throws MojoExecutionException { - for ( Object provided : getScopeState().provided.values() ) + for ( WeakMojoExecutionListener provided : getProvidedListeners() ) { - if ( provided instanceof WeakMojoExecutionListener ) - { - ( (WeakMojoExecutionListener) provided ).afterMojoExecutionSuccess( event ); - } + provided.afterMojoExecutionSuccess( event ); } } public void afterExecutionFailure( MojoExecutionEvent event ) { + for ( WeakMojoExecutionListener provided : getProvidedListeners() ) + { + provided.afterExecutionFailure( event ); + } + } + + private Collection getProvidedListeners() + { + // the same instance can be provided multiple times under different Key's + // deduplicate instances to avoid redundant beforeXXX/afterXXX callbacks + IdentityHashMap listeners = + new IdentityHashMap(); for ( Object provided : getScopeState().provided.values() ) { if ( provided instanceof WeakMojoExecutionListener ) { - ( (WeakMojoExecutionListener) provided ).afterExecutionFailure( event ); + listeners.put( (WeakMojoExecutionListener) provided, null ); } } + return listeners.keySet(); } - } diff --git a/maven-core/src/test/java/org/apache/maven/execution/scope/internal/MojoExecutionScopeTest.java b/maven-core/src/test/java/org/apache/maven/execution/scope/internal/MojoExecutionScopeTest.java index 6e6f9feee0..a4eb354cdb 100644 --- a/maven-core/src/test/java/org/apache/maven/execution/scope/internal/MojoExecutionScopeTest.java +++ b/maven-core/src/test/java/org/apache/maven/execution/scope/internal/MojoExecutionScopeTest.java @@ -14,9 +14,16 @@ */ package org.apache.maven.execution.scope.internal; +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.maven.execution.MojoExecutionEvent; +import org.apache.maven.execution.scope.WeakMojoExecutionListener; +import org.apache.maven.plugin.MojoExecutionException; + import junit.framework.TestCase; import com.google.inject.Key; +import com.google.inject.Provider; public class MojoExecutionScopeTest extends TestCase @@ -45,9 +52,71 @@ public void testNestedEnter() try { scope.exit(); + fail(); } catch ( IllegalStateException expected ) { } } + + public void testMultiKeyInstance() + throws Exception + { + MojoExecutionScope scope = new MojoExecutionScope(); + scope.enter(); + + final AtomicInteger beforeExecution = new AtomicInteger(); + final AtomicInteger afterExecutionSuccess = new AtomicInteger(); + final AtomicInteger afterExecutionFailure = new AtomicInteger(); + final WeakMojoExecutionListener instance = new WeakMojoExecutionListener() + { + @Override + public void beforeMojoExecution( MojoExecutionEvent event ) + throws MojoExecutionException + { + beforeExecution.incrementAndGet(); + } + + @Override + public void afterMojoExecutionSuccess( MojoExecutionEvent event ) + throws MojoExecutionException + { + afterExecutionSuccess.incrementAndGet(); + } + + @Override + public void afterExecutionFailure( MojoExecutionEvent event ) + { + afterExecutionFailure.incrementAndGet(); + } + }; + assertSame( instance, scope.scope( Key.get( Object.class ), new Provider() + { + @Override + public Object get() + { + return instance; + } + } ).get() ); + assertSame( instance, + scope.scope( Key.get( WeakMojoExecutionListener.class ), new Provider() + { + @Override + public WeakMojoExecutionListener get() + { + return instance; + } + } ).get() ); + + final MojoExecutionEvent event = new MojoExecutionEvent( null, null, null, null ); + scope.beforeMojoExecution( event ); + scope.afterMojoExecutionSuccess( event ); + scope.afterExecutionFailure( event ); + + assertEquals( 1, beforeExecution.get() ); + assertEquals( 1, afterExecutionSuccess.get() ); + assertEquals( 1, afterExecutionFailure.get() ); + + scope.exit(); + } }