diff --git a/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java b/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java index 70ada9e260..9c9357d4b0 100644 --- a/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java +++ b/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java @@ -22,6 +22,7 @@ package org.apache.maven.execution; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.errors.CoreErrorReporter; import org.apache.maven.monitor.event.EventMonitor; +import org.apache.maven.monitor.event.MavenWorkspaceMonitor; import org.apache.maven.profiles.ProfileManager; import org.apache.maven.profiles.activation.ProfileActivationContext; import org.apache.maven.project.DefaultProjectBuilderConfiguration; @@ -101,6 +102,8 @@ public class DefaultMavenExecutionRequest private List eventMonitors; + private MavenWorkspaceMonitor workspaceMonitor; + private List activeProfiles; private List inactiveProfiles; @@ -709,6 +712,17 @@ public class DefaultMavenExecutionRequest return this; } + public MavenWorkspaceMonitor getWorkspaceMonitor() + { + return workspaceMonitor; + } + + public MavenExecutionRequest setWorkspaceMonitor( MavenWorkspaceMonitor workspaceMonitor ) + { + this.workspaceMonitor = workspaceMonitor; + return this; + } + public Properties getUserProperties() { return userProperties; diff --git a/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java b/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java index ee18beb8d1..42b74da0be 100644 --- a/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java +++ b/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java @@ -23,6 +23,7 @@ import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; import org.apache.maven.errors.CoreErrorReporter; import org.apache.maven.monitor.event.EventMonitor; +import org.apache.maven.monitor.event.MavenWorkspaceMonitor; import org.apache.maven.profiles.ProfileManager; import org.apache.maven.profiles.activation.ProfileActivationContext; import org.apache.maven.project.ProjectBuilderConfiguration; @@ -221,5 +222,8 @@ public interface MavenExecutionRequest MavenExecutionRequest setErrorReporter( CoreErrorReporter reporter ); CoreErrorReporter getErrorReporter(); + MavenExecutionRequest setWorkspaceMonitor( MavenWorkspaceMonitor workspaceMonitor ); + MavenWorkspaceMonitor getWorkspaceMonitor(); + ProjectBuilderConfiguration getProjectBuildingConfiguration(); } diff --git a/maven-core/src/main/java/org/apache/maven/monitor/event/AbstractWorkspaceMonitor.java b/maven-core/src/main/java/org/apache/maven/monitor/event/AbstractWorkspaceMonitor.java new file mode 100644 index 0000000000..91c7538686 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/monitor/event/AbstractWorkspaceMonitor.java @@ -0,0 +1,25 @@ +package org.apache.maven.monitor.event; + +import org.apache.maven.workspace.MavenWorkspaceStore; + +public abstract class AbstractWorkspaceMonitor + extends AbstractEmbedderLifecycleMonitor + implements MavenWorkspaceMonitor +{ + + private MavenWorkspaceStore workspaceManager; + + public void setWorkspaceStore( MavenWorkspaceStore workspaceManager ) + { + this.workspaceManager = workspaceManager; + } + + /* (non-Javadoc) + * @see org.apache.maven.embedder.lifecycle.MavenWorkspaceMonitor#clearCache() + */ + public void clearCache() + { + workspaceManager.clear(); + } + +} \ No newline at end of file diff --git a/maven-core/src/main/java/org/apache/maven/monitor/event/MavenWorkspaceMonitor.java b/maven-core/src/main/java/org/apache/maven/monitor/event/MavenWorkspaceMonitor.java new file mode 100644 index 0000000000..c0cbc84ccd --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/monitor/event/MavenWorkspaceMonitor.java @@ -0,0 +1,13 @@ +package org.apache.maven.monitor.event; + +import org.apache.maven.workspace.MavenWorkspaceStore; + +public interface MavenWorkspaceMonitor + extends EventMonitor +{ + + void setWorkspaceStore( MavenWorkspaceStore workspaceStore ); + + void clearCache(); + +} diff --git a/maven-core/src/main/java/org/apache/maven/monitor/event/OnStopWorkspaceMonitor.java b/maven-core/src/main/java/org/apache/maven/monitor/event/OnStopWorkspaceMonitor.java new file mode 100644 index 0000000000..655d0deebc --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/monitor/event/OnStopWorkspaceMonitor.java @@ -0,0 +1,12 @@ +package org.apache.maven.monitor.event; + +public class OnStopWorkspaceMonitor + extends AbstractWorkspaceMonitor +{ + + public void embedderStopped( long timestamp ) + { + clearCache(); + } + +} diff --git a/maven-core/src/main/java/org/apache/maven/monitor/event/PerCallWorkspaceMonitor.java b/maven-core/src/main/java/org/apache/maven/monitor/event/PerCallWorkspaceMonitor.java new file mode 100644 index 0000000000..e0aea4fd87 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/monitor/event/PerCallWorkspaceMonitor.java @@ -0,0 +1,23 @@ +package org.apache.maven.monitor.event; + + + +public class PerCallWorkspaceMonitor + extends AbstractWorkspaceMonitor +{ + + public void embedderMethodEnded( String method, + long timestamp ) + { + clearCache(); + } + + // Be double-sure that the cache is cleared when the embedder stops. + public void embedderStopped( long timestamp ) + { + clearCache(); + } + + + +} diff --git a/maven-embedder/src/main/java/org/apache/maven/embedder/Configuration.java b/maven-embedder/src/main/java/org/apache/maven/embedder/Configuration.java index 97e225eb53..ae5d8e976e 100644 --- a/maven-embedder/src/main/java/org/apache/maven/embedder/Configuration.java +++ b/maven-embedder/src/main/java/org/apache/maven/embedder/Configuration.java @@ -20,6 +20,7 @@ package org.apache.maven.embedder; import org.apache.maven.errors.CoreErrorReporter; import org.apache.maven.monitor.event.EventMonitor; +import org.apache.maven.monitor.event.MavenWorkspaceMonitor; import org.apache.maven.realm.MavenRealmManager; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.classworlds.ClassWorld; @@ -151,4 +152,8 @@ public interface Configuration Configuration setEventMonitors( List eventMonitors ); List getEventMonitors(); + + Configuration setWorkspaceMonitor( MavenWorkspaceMonitor workspaceMonitor ); + + MavenWorkspaceMonitor getWorkspaceMonitor(); } diff --git a/maven-embedder/src/main/java/org/apache/maven/embedder/DefaultConfiguration.java b/maven-embedder/src/main/java/org/apache/maven/embedder/DefaultConfiguration.java index dbd03bf34e..2ecc3156e3 100644 --- a/maven-embedder/src/main/java/org/apache/maven/embedder/DefaultConfiguration.java +++ b/maven-embedder/src/main/java/org/apache/maven/embedder/DefaultConfiguration.java @@ -20,6 +20,7 @@ package org.apache.maven.embedder; import org.apache.maven.errors.CoreErrorReporter; import org.apache.maven.monitor.event.EventMonitor; +import org.apache.maven.monitor.event.MavenWorkspaceMonitor; import org.apache.maven.realm.MavenRealmManager; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.classworlds.ClassWorld; @@ -68,6 +69,8 @@ public class DefaultConfiguration /** List<EventMonitor>. */ private List eventMonitors; + private MavenWorkspaceMonitor workspaceMonitor; + /** Creates a new instance of DefaultConfiguration */ public DefaultConfiguration() { @@ -273,4 +276,15 @@ public class DefaultConfiguration this.eventMonitors = eventMonitors; return this; } + + public MavenWorkspaceMonitor getWorkspaceMonitor() + { + return workspaceMonitor; + } + + public Configuration setWorkspaceMonitor( MavenWorkspaceMonitor workspaceMonitor ) + { + this.workspaceMonitor = workspaceMonitor; + return this; + } } diff --git a/maven-embedder/src/main/java/org/apache/maven/embedder/MavenEmbedder.java b/maven-embedder/src/main/java/org/apache/maven/embedder/MavenEmbedder.java index 9ac8a64fef..d28acc7de7 100644 --- a/maven-embedder/src/main/java/org/apache/maven/embedder/MavenEmbedder.java +++ b/maven-embedder/src/main/java/org/apache/maven/embedder/MavenEmbedder.java @@ -167,6 +167,9 @@ public class MavenEmbedder private BuildPlanner buildPlanner; + // TODO: Remove this once we have better control over cache-cleaning. + private MavenWorkspaceStore workspaceStore; + // ---------------------------------------------------------------------- // Configuration // ---------------------------------------------------------------------- @@ -200,6 +203,11 @@ public class MavenEmbedder return request; } + protected MavenWorkspaceStore getWorkspaceStore() + { + return workspaceStore; + } + // ---------------------------------------------------------------------- // Accessors // ---------------------------------------------------------------------- @@ -702,6 +710,8 @@ public class MavenEmbedder buildPlanner = (BuildPlanner) container.lookup( BuildPlanner.class ); + workspaceStore = (MavenWorkspaceStore) container.lookup( MavenWorkspaceStore.class ); + artifactHandlerManager = (ArtifactHandlerManager) container.lookup( ArtifactHandlerManager.ROLE ); // This is temporary as we can probably cache a single request and use it for default values and diff --git a/maven-embedder/src/main/java/org/apache/maven/embedder/execution/DefaultMavenExecutionRequestPopulator.java b/maven-embedder/src/main/java/org/apache/maven/embedder/execution/DefaultMavenExecutionRequestPopulator.java index bc991cd2a7..9b18f146cf 100644 --- a/maven-embedder/src/main/java/org/apache/maven/embedder/execution/DefaultMavenExecutionRequestPopulator.java +++ b/maven-embedder/src/main/java/org/apache/maven/embedder/execution/DefaultMavenExecutionRequestPopulator.java @@ -34,6 +34,8 @@ import org.apache.maven.model.Profile; import org.apache.maven.model.Repository; import org.apache.maven.monitor.event.DefaultEventMonitor; import org.apache.maven.monitor.event.EventMonitor; +import org.apache.maven.monitor.event.MavenWorkspaceMonitor; +import org.apache.maven.monitor.event.PerCallWorkspaceMonitor; import org.apache.maven.plugin.Mojo; import org.apache.maven.profiles.DefaultProfileManager; import org.apache.maven.profiles.ProfileManager; @@ -94,6 +96,8 @@ public class DefaultMavenExecutionRequestPopulator private WagonManager wagonManager; + private MavenWorkspaceStore workspaceManager; + private MavenSettingsBuilder settingsBuilder; public MavenExecutionRequest populateDefaults( MavenExecutionRequest request, @@ -102,6 +106,8 @@ public class DefaultMavenExecutionRequestPopulator { eventing( request, configuration ); + workspaceMonitor( request, configuration ); + reporter( request, configuration ); executionProperties( request, configuration ); @@ -130,6 +136,44 @@ public class DefaultMavenExecutionRequestPopulator return request; } + private void workspaceMonitor( MavenExecutionRequest request, + Configuration configuration ) + { + MavenWorkspaceMonitor workspaceMonitor = request.getWorkspaceMonitor(); + + if ( workspaceMonitor == null ) + { + workspaceMonitor = configuration.getWorkspaceMonitor(); + } + + List requestEventMonitors = request.getEventMonitors(); + if ( ( requestEventMonitors != null ) && !requestEventMonitors.isEmpty() ) + { + for ( Iterator it = requestEventMonitors.iterator(); it.hasNext(); ) + { + Object monitor = it.next(); + if ( monitor instanceof MavenWorkspaceMonitor ) + { + if ( workspaceMonitor == null ) + { + workspaceMonitor = (MavenWorkspaceMonitor) monitor; + } + it.remove(); + break; + } + } + } + + if ( workspaceMonitor == null ) + { + workspaceMonitor = new PerCallWorkspaceMonitor(); + } + + workspaceMonitor.setWorkspaceStore( workspaceManager ); + + request.addEventMonitor( workspaceMonitor ); + } + private void reporter( MavenExecutionRequest request, Configuration configuration ) { diff --git a/maven-embedder/src/main/resources/META-INF/plexus/components.xml b/maven-embedder/src/main/resources/META-INF/plexus/components.xml index 7eba653420..e797122f66 100644 --- a/maven-embedder/src/main/resources/META-INF/plexus/components.xml +++ b/maven-embedder/src/main/resources/META-INF/plexus/components.xml @@ -23,6 +23,9 @@ under the License. org.apache.maven.embedder.execution.MavenExecutionRequestPopulator org.apache.maven.embedder.execution.DefaultMavenExecutionRequestPopulator + + org.apache.maven.workspace.MavenWorkspaceStore + org.apache.maven.artifact.manager.WagonManager default @@ -72,5 +75,6 @@ under the License. + diff --git a/maven-embedder/src/test/java/org/apache/maven/embedder/MavenEmbedderEventingTest.java b/maven-embedder/src/test/java/org/apache/maven/embedder/MavenEmbedderEventingTest.java new file mode 100644 index 0000000000..af01b46b0c --- /dev/null +++ b/maven-embedder/src/test/java/org/apache/maven/embedder/MavenEmbedderEventingTest.java @@ -0,0 +1,261 @@ +package org.apache.maven.embedder; + +import org.apache.maven.execution.DefaultMavenExecutionRequest; +import org.apache.maven.execution.MavenExecutionRequest; +import org.apache.maven.extension.ExtensionScanningException; +import org.apache.maven.monitor.event.AbstractWorkspaceMonitor; +import org.apache.maven.project.ProjectBuildingException; +import org.apache.maven.reactor.MavenExecutionException; +import org.apache.maven.workspace.MavenWorkspaceStore; +import org.codehaus.plexus.util.FileUtils; + +import java.io.File; +import java.io.IOException; +import java.util.Collections; + +import junit.framework.TestCase; + +public class MavenEmbedderEventingTest + extends TestCase +{ + + protected String basedir; + + protected void setUp() + throws Exception + { + super.setUp(); + + basedir = System.getProperty( "basedir" ); + + if ( basedir == null ) + { + basedir = new File( "." ).getCanonicalPath(); + } + } + + public void testEmbedderInitializeAndStopEventsFired() + throws MavenEmbedderException + { + TestWorkspaceMonitor testWSMonitor = new TestWorkspaceMonitor(); + + Configuration config = new DefaultConfiguration(); + config.setWorkspaceMonitor( testWSMonitor ); + + assertEquals( 0, testWSMonitor.initializeCaught ); + assertEquals( 0, testWSMonitor.setManagerCaught ); + + MavenEmbedder embedder = new MavenEmbedder( config ); + + assertEquals( 1, testWSMonitor.initializeCaught ); + assertEquals( 1, testWSMonitor.setManagerCaught ); + + assertEquals( 0, testWSMonitor.stopCaught ); + assertEquals( 0, testWSMonitor.clearCaught ); + + assertSame( embedder.getWorkspaceStore(), testWSMonitor.workspaceManager ); + + embedder.stop(); + + assertEquals( 1, testWSMonitor.stopCaught ); + assertEquals( 1, testWSMonitor.clearCaught ); + + assertEquals( 0, testWSMonitor.startMethodCaught ); + assertEquals( 0, testWSMonitor.endMethodCaught ); + } + + public void testStartAndEndMethodEventsFiredOnSimpleReadProject() + throws IOException, MavenEmbedderException, ProjectBuildingException, + ExtensionScanningException, MavenExecutionException + { + EmbedderAndMonitor em = newEmbedder(); + + assertEquals( 0, em.monitor.startMethodCaught ); + assertEquals( 0, em.monitor.endMethodCaught ); + + File dir = getFile( "simple-read-project" ); + File pomFile = new File( dir, "pom.xml" ); + + em.embedder.readProject( pomFile ); + + assertEquals( 1, em.monitor.startMethodCaught ); + assertEquals( 1, em.monitor.endMethodCaught ); + assertEquals( 1, em.monitor.clearCaught ); + + assertSame( em.embedder.getWorkspaceStore(), em.monitor.workspaceManager ); + + em.embedder.stop(); + } + + public void testStartAndEndMethodEventsFiredOnReadWithDeps() + throws IOException, MavenEmbedderException, ProjectBuildingException, + ExtensionScanningException, MavenExecutionException + { + File dir = getFile( "read-with-deps" ); + File pomFile = new File( dir, "pom.xml" ); + File localRepoDir = new File( dir, "repo" ); + + EmbedderAndMonitor em = newEmbedder( localRepoDir ); + + assertEquals( 0, em.monitor.startMethodCaught ); + assertEquals( 0, em.monitor.endMethodCaught ); + + em.embedder.readProject( pomFile ); + + assertEquals( 1, em.monitor.startMethodCaught ); + assertEquals( 1, em.monitor.endMethodCaught ); + assertEquals( 1, em.monitor.clearCaught ); + + assertSame( em.embedder.getWorkspaceStore(), em.monitor.workspaceManager ); + + em.embedder.stop(); + } + + public void testStartAndEndMethodEventsFiredOnExecute() + throws IOException, MavenEmbedderException, ProjectBuildingException, + ExtensionScanningException, MavenExecutionException + { + EmbedderAndMonitor em = newEmbedder(); + + assertEquals( 0, em.monitor.startMethodCaught ); + assertEquals( 0, em.monitor.endMethodCaught ); + + File dir = getFile( "simple-read-project" ); + + MavenExecutionRequest request = new DefaultMavenExecutionRequest(); + request.setGoals( Collections.singletonList( "clean" ) ); + request.setBaseDirectory( dir ); + + em.embedder.execute( request ); + + assertEquals( 1, em.monitor.startMethodCaught ); + assertEquals( 1, em.monitor.endMethodCaught ); + assertEquals( 1, em.monitor.clearCaught ); + + assertSame( em.embedder.getWorkspaceStore(), em.monitor.workspaceManager ); + + em.embedder.stop(); + } + + private EmbedderAndMonitor newEmbedder() + throws MavenEmbedderException + { + return newEmbedder( null ); + } + + private EmbedderAndMonitor newEmbedder( File localRepoDir ) + throws MavenEmbedderException + { + TestWorkspaceMonitor testWSMonitor = new TestWorkspaceMonitor(); + + Configuration config = new DefaultConfiguration(); + config.setWorkspaceMonitor( testWSMonitor ); + config.setMavenEmbedderLogger( new MavenEmbedderConsoleLogger() ); + + if ( localRepoDir != null ) + { + config.setLocalRepository( localRepoDir ); + } + + return new EmbedderAndMonitor( new MavenEmbedder( config ), testWSMonitor ); + } + + private static final class EmbedderAndMonitor + { + private MavenEmbedder embedder; + + private TestWorkspaceMonitor monitor; + + private EmbedderAndMonitor( MavenEmbedder embedder, + TestWorkspaceMonitor monitor ) + { + this.embedder = embedder; + this.monitor = monitor; + } + } + + private File getFile( String path ) + throws IOException + { + File testDirectory = new File( basedir, "src/test/eventing-projects/" + path ); + + System.out.println( "Test source dir: " + testDirectory ); + + File targetDirectory = new File( basedir, "target/eventing-projects/" + path ); + + System.out.println( "Test temp dir: " + targetDirectory ); + + targetDirectory.getParentFile().mkdirs(); + + FileUtils.copyDirectoryStructure( testDirectory, targetDirectory ); + + return targetDirectory; + } + + private static final class TestWorkspaceMonitor + extends AbstractWorkspaceMonitor + { + + private int initializeCaught = 0; + + private int startMethodCaught = 0; + + private int endMethodCaught = 0; + + private int stopCaught = 0; + + private int setManagerCaught = 0; + + private int clearCaught = 0; + + private MavenWorkspaceStore workspaceManager; + + private boolean clearOnEndMethod = true; + + private boolean clearOnStop = true; + + public void embedderInitialized( long timestamp ) + { + initializeCaught++; + } + + public void embedderMethodEnded( String method, + long timestamp ) + { + endMethodCaught++; + if ( clearOnEndMethod ) + { + clearCache(); + } + } + + public void embedderMethodStarted( String method, + long timestamp ) + { + startMethodCaught++; + } + + public void embedderStopped( long timestamp ) + { + stopCaught++; + if ( clearOnStop ) + { + clearCache(); + } + } + + public void setWorkspaceStore( MavenWorkspaceStore workspaceManager ) + { + setManagerCaught++; + this.workspaceManager = workspaceManager; + super.setWorkspaceStore( workspaceManager ); + } + + public void clearCache() + { + clearCaught++; + super.clearCache(); + } + + } +} diff --git a/pom.xml b/pom.xml index 3588392954..c36b40542b 100644 --- a/pom.xml +++ b/pom.xml @@ -256,6 +256,7 @@ maven-project maven-reporting-api maven-embedder + maven-workspace maven-toolchain @@ -266,7 +267,7 @@ 1.0-alpha-9 1.2_Java1.3 3.8.1 - 1.0-alpha-50-SNAPSHOT + 1.0-alpha-48 1.0-alpha-6 1.1 1.5.5