o hide the creation of default event dispatcher and reactor manager inside the session

o the lifecycle executor test is now starting to look sane


git-svn-id: https://svn.apache.org/repos/asf/maven/components/branches/MNG-2766@757635 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Jason van Zyl 2009-03-24 01:43:43 +00:00
parent c981673e9e
commit ace03b781b
7 changed files with 57 additions and 288 deletions

View File

@ -40,7 +40,6 @@ import org.apache.maven.lifecycle.Lifecycle;
import org.apache.maven.lifecycle.LifecycleExecutionException;
import org.apache.maven.lifecycle.LifecycleExecutor;
import org.apache.maven.monitor.event.DefaultEventDispatcher;
import org.apache.maven.monitor.event.DeprecationEventDispatcher;
import org.apache.maven.monitor.event.EventDispatcher;
import org.apache.maven.monitor.event.MavenEvents;
import org.apache.maven.project.MavenProject;

View File

@ -20,6 +20,7 @@ package org.apache.maven.execution;
*/
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedHashMap;
@ -29,6 +30,7 @@ import java.util.Properties;
import java.util.Set;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.monitor.event.DefaultEventDispatcher;
import org.apache.maven.monitor.event.EventDispatcher;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
@ -37,7 +39,7 @@ import org.apache.maven.project.ProjectBuilderConfiguration;
import org.apache.maven.reporting.MavenReport;
import org.apache.maven.settings.Settings;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.util.dag.CycleDetectedException;
/**
* @author Jason van Zyl
@ -61,13 +63,35 @@ public class MavenSession
private ArtifactRepository localRepository;
private List<String> pluginGroups;
public MavenSession( ArtifactRepository localRepository, List<String> pluginGroups )
{
this.localRepository = localRepository;
this.pluginGroups = pluginGroups;
// Used by the embedder to verifyPlugin
public MavenSession( PlexusContainer container, MavenExecutionRequest request )
{
this.container = container;
this.request = request;
}
public MavenSession( PlexusContainer container, MavenExecutionRequest request, MavenProject project )
throws CycleDetectedException, DuplicateProjectException
{
this.container = container;
this.request = request;
this.reactorManager = new ReactorManager( Arrays.asList( new MavenProject[]{ project } ), request.getReactorFailureBehavior() );
this.eventDispatcher = new DefaultEventDispatcher( request.getEventMonitors() );
// When we pass in one project we'll just set the current project.
this.currentProject = project;
}
public MavenSession( PlexusContainer container, MavenExecutionRequest request, List<MavenProject> projects )
throws CycleDetectedException, DuplicateProjectException
{
this.container = container;
this.request = request;
this.reactorManager = new ReactorManager( projects, request.getReactorFailureBehavior() );
this.eventDispatcher = new DefaultEventDispatcher( request.getEventMonitors() );
}
//TODO: get rid of this
public MavenSession( PlexusContainer container, MavenExecutionRequest request, ReactorManager reactorManager )
{
this.container = container;
@ -75,10 +99,11 @@ public class MavenSession
this.reactorManager = reactorManager;
}
public MavenSession( PlexusContainer container, MavenExecutionRequest request, ReactorManager reactorManager, EventDispatcher Eventdispatcher )
//TODO: get rid of this
public MavenSession( PlexusContainer container, MavenExecutionRequest request, ReactorManager reactorManager, EventDispatcher eventdispatcher )
{
this( container, request, reactorManager );
this.eventDispatcher = Eventdispatcher;
this.eventDispatcher = eventdispatcher;
}
public Map<String,Object> getPluginContext( PluginDescriptor pluginDescriptor, MavenProject project )
@ -120,42 +145,6 @@ public class MavenSession
//
// ----------------------------------------------------------------------
public Object lookup( String role )
throws ComponentLookupException
{
return container.lookup( role );
}
public Object lookup( String role, String roleHint )
throws ComponentLookupException
{
return container.lookup( role, roleHint );
}
public <T> T lookup( Class<T> type )
throws ComponentLookupException
{
return container.lookup( type );
}
public <T> T lookup( Class<T> type, String roleHint )
throws ComponentLookupException
{
return container.lookup( type, roleHint );
}
public List<Object> lookupList( String role )
throws ComponentLookupException
{
return container.lookupList( role );
}
public Map<String,Object> lookupMap( String role )
throws ComponentLookupException
{
return container.lookupMap( role );
}
public EventDispatcher getEventDispatcher()
{
return eventDispatcher;

View File

@ -20,19 +20,16 @@ package org.apache.maven.execution;
*/
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.maven.artifact.ArtifactUtils;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.execution.DuplicateProjectException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.ReportPlugin;
import org.apache.maven.model.Extension;
import org.codehaus.plexus.util.dag.CycleDetectedException;
import org.codehaus.plexus.util.dag.DAG;
import org.codehaus.plexus.util.dag.TopologicalSorter;
import java.util.*;
public class ReactorManager
{
@ -189,210 +186,4 @@ public class ReactorManager
{
return buildFailuresByProject.size() + buildSuccessesByProject.size() > 1;
}
protected static class ProjectSorter
{
private final DAG dag;
private final List<MavenProject> sortedProjects;
private MavenProject topLevelProject;
/**
* Sort a list of projects.
* <ul>
* <li>collect all the vertices for the projects that we want to build.</li>
* <li>iterate through the deps of each project and if that dep is within
* the set of projects we want to build then add an edge, otherwise throw
* the edge away because that dependency is not within the set of projects
* we are trying to build. we assume a closed set.</li>
* <li>do a topo sort on the graph that remains.</li>
* </ul>
* @throws DuplicateProjectException if any projects are duplicated by id
*/
// MAVENAPI FIXME: the DAG used is NOT only used to represent the dependency relation,
// but also for <parent>, <build><plugin>, <reports>. We need multiple DAG's
// since a DAG can only handle 1 type of relationship properly.
// Usecase: This is detected as a cycle:
// org.apache.maven:maven-plugin-api -(PARENT)->
// org.apache.maven:maven -(inherited REPORTING)->
// org.apache.maven.plugins:maven-checkstyle-plugin -(DEPENDENCY)->
// org.apache.maven:maven-plugin-api
// In this case, both the verify and the report goals are called
// in a different lifecycle. Though the compiler-plugin has a valid usecase, although
// that seems to work fine. We need to take versions and lifecycle into account.
public ProjectSorter( List<MavenProject> projects )
throws CycleDetectedException, DuplicateProjectException
{
dag = new DAG();
Map projectMap = new HashMap();
for ( Iterator i = projects.iterator(); i.hasNext(); )
{
MavenProject project = (MavenProject) i.next();
String id = ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() );
if ( dag.getVertex( id ) != null )
{
MavenProject conflictingProject = (MavenProject) projectMap.get( id );
throw new DuplicateProjectException( id,
conflictingProject.getFile(),
project.getFile(),
"Project '"
+ id
+ "' is duplicated in the reactor" );
}
dag.addVertex( id );
projectMap.put( id, project );
}
for ( Iterator i = projects.iterator(); i.hasNext(); )
{
MavenProject project = (MavenProject) i.next();
String id = ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() );
for ( Iterator j = project.getDependencies().iterator(); j.hasNext(); )
{
Dependency dependency = (Dependency) j.next();
String dependencyId = ArtifactUtils
.versionlessKey( dependency.getGroupId(), dependency.getArtifactId() );
if ( dag.getVertex( dependencyId ) != null )
{
project.addProjectReference( (MavenProject) projectMap.get( dependencyId ) );
dag.addEdge( id, dependencyId );
}
}
MavenProject parent = project.getParent();
if ( parent != null )
{
String parentId = ArtifactUtils.versionlessKey( parent.getGroupId(), parent.getArtifactId() );
if ( dag.getVertex( parentId ) != null )
{
// Parent is added as an edge, but must not cause a cycle - so we remove any other edges it has in conflict
if ( dag.hasEdge( parentId, id ) )
{
dag.removeEdge( parentId, id );
}
dag.addEdge( id, parentId );
}
}
List buildPlugins = project.getBuildPlugins();
if ( buildPlugins != null )
{
for ( Iterator j = buildPlugins.iterator(); j.hasNext(); )
{
Plugin plugin = (Plugin) j.next();
String pluginId = ArtifactUtils.versionlessKey( plugin.getGroupId(), plugin.getArtifactId() );
if ( ( dag.getVertex( pluginId ) != null ) && !pluginId.equals( id ) )
{
addEdgeWithParentCheck( projectMap, pluginId, project, id );
}
}
}
List reportPlugins = project.getReportPlugins();
if ( reportPlugins != null )
{
for ( Iterator j = reportPlugins.iterator(); j.hasNext(); )
{
ReportPlugin plugin = (ReportPlugin) j.next();
String pluginId = ArtifactUtils.versionlessKey( plugin.getGroupId(), plugin.getArtifactId() );
if ( ( dag.getVertex( pluginId ) != null ) && !pluginId.equals( id ) )
{
addEdgeWithParentCheck( projectMap, pluginId, project, id );
}
}
}
for ( Iterator j = project.getBuildExtensions().iterator(); j.hasNext(); )
{
Extension extension = (Extension) j.next();
String extensionId = ArtifactUtils.versionlessKey( extension.getGroupId(), extension.getArtifactId() );
if ( dag.getVertex( extensionId ) != null )
{
addEdgeWithParentCheck( projectMap, extensionId, project, id );
}
}
}
List sortedProjects = new ArrayList();
for ( Iterator i = TopologicalSorter.sort( dag ).iterator(); i.hasNext(); )
{
String id = (String) i.next();
sortedProjects.add( projectMap.get( id ) );
}
this.sortedProjects = Collections.unmodifiableList( sortedProjects );
}
private void addEdgeWithParentCheck( Map projectMap, String projectRefId, MavenProject project, String id )
throws CycleDetectedException
{
MavenProject extProject = (MavenProject) projectMap.get( projectRefId );
if ( extProject == null )
{
return;
}
project.addProjectReference( extProject );
MavenProject extParent = extProject.getParent();
if ( extParent != null )
{
String parentId = ArtifactUtils.versionlessKey( extParent.getGroupId(), extParent.getArtifactId() );
// Don't add edge from parent to extension if a reverse edge already exists
if ( !dag.hasEdge( projectRefId, id ) || !parentId.equals( id ) )
{
dag.addEdge( id, projectRefId );
}
}
}
// TODO: !![jc; 28-jul-2005] check this; if we're using '-r' and there are aggregator tasks, this will result in weirdness.
public MavenProject getTopLevelProject()
{
if ( topLevelProject == null )
{
for ( Iterator i = sortedProjects.iterator(); i.hasNext() && ( topLevelProject == null ); )
{
MavenProject project = (MavenProject) i.next();
if ( project.isExecutionRoot() )
{
topLevelProject = project;
}
}
}
return topLevelProject;
}
public List<MavenProject> getSortedProjects()
{
return sortedProjects;
}
public boolean hasMultipleProjects()
{
return sortedProjects.size() > 1;
}
private List getDependents( String id )
{
return dag.getParentLabels( id );
}
}
}

View File

@ -19,19 +19,19 @@ package org.apache.maven.execution;
* under the License.
*/
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import junit.framework.TestCase;
import org.apache.maven.model.Build;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Extension;
import org.apache.maven.model.Model;
import org.apache.maven.execution.DuplicateProjectException;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.dag.CycleDetectedException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Test sorting projects by dependencies.
*
@ -64,7 +64,7 @@ public class ProjectSorterTest
build.addExtension( extension );
new ReactorManager.ProjectSorter( Collections.singletonList( project ) );
new ProjectSorter( Collections.singletonList( project ) );
}
public void testMatchingArtifactIdsDifferentGroupIds()
@ -77,7 +77,7 @@ public class ProjectSorterTest
projects.add( project2 );
project1.getDependencies().add( createDependency( project2 ) );
projects = new ReactorManager.ProjectSorter( projects ).getSortedProjects();
projects = new ProjectSorter( projects ).getSortedProjects();
assertEquals( project2, projects.get( 0 ) );
assertEquals( project1, projects.get( 1 ) );
@ -93,7 +93,7 @@ public class ProjectSorterTest
projects.add( project2 );
project1.getDependencies().add( createDependency( project2 ) );
projects = new ReactorManager.ProjectSorter( projects ).getSortedProjects();
projects = new ProjectSorter( projects ).getSortedProjects();
assertEquals( project2, projects.get( 0 ) );
assertEquals( project1, projects.get( 1 ) );
@ -110,7 +110,7 @@ public class ProjectSorterTest
try
{
projects = new ReactorManager.ProjectSorter( projects ).getSortedProjects();
projects = new ProjectSorter( projects ).getSortedProjects();
fail( "Duplicate projects should fail" );
}
catch ( DuplicateProjectException e )
@ -131,7 +131,7 @@ public class ProjectSorterTest
try
{
projects = new ReactorManager.ProjectSorter( projects ).getSortedProjects();
projects = new ProjectSorter( projects ).getSortedProjects();
fail( "Duplicate projects should fail" );
}
catch ( DuplicateProjectException e )

View File

@ -10,10 +10,7 @@ import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.execution.DefaultMavenExecutionRequest;
import org.apache.maven.execution.MavenExecutionRequest;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.execution.ReactorManager;
import org.apache.maven.monitor.event.DefaultEventDispatcher;
import org.apache.maven.monitor.event.DefaultEventMonitor;
import org.apache.maven.monitor.event.EventDispatcher;
import org.apache.maven.plugin.MavenPluginCollector;
import org.apache.maven.plugin.MavenPluginDiscoverer;
import org.apache.maven.plugin.MojoExecution;
@ -157,8 +154,10 @@ public class LifecycleExecutorTest
containerConfiguration.addComponentDiscoveryListener( new MavenPluginCollector() );
}
//TODO: this is still a narly mess and shows it's still not layered properly. Once these tests look
// a little better i'll be ready for the next round of refactoring in the plugin manager.
// - remove the event monitor, just default or get rid of it
// layer the creation of a project builder configuration with a request, but this will need to be
// a Maven subclass because we don't want to couple maven to the project builder which we need to
// separate.
protected MavenSession createMavenSession( File pom )
throws Exception
{
@ -180,17 +179,8 @@ public class LifecycleExecutorTest
.setRemoteRepositories( Arrays.asList( remoteRepository ) );
MavenProject project = projectBuilder.build( pom, configuration );
List projects = new ArrayList();
projects.add( project );
ReactorManager reactorManager = new ReactorManager( projects, request.getReactorFailureBehavior() );
EventDispatcher dispatcher = new DefaultEventDispatcher( request.getEventMonitors() );
MavenSession session = new MavenSession( getContainer(), request, reactorManager, dispatcher );
//!!jvz This is not really quite right, take a look at how this actually works.
session.setCurrentProject( project );
MavenSession session = new MavenSession( getContainer(), request, project );
return session;
}

View File

@ -352,7 +352,7 @@ public class PluginParameterExpressionEvaluatorTest
.setBaseDirectory( new File( "" ) )
.setLocalRepository( repo );
return new MavenSession( container, request, null );
return new MavenSession( container, request, (List)null );
}
public void testLocalRepositoryExtraction()

View File

@ -279,7 +279,7 @@ public class MavenEmbedder
protected void verifyPlugin( Plugin plugin, MavenProject project )
throws ComponentLookupException, PluginLoaderException
{
MavenSession session = new MavenSession( container, request, null );
MavenSession session = new MavenSession( container, request );
pluginManager.loadPlugin( plugin, project, session );
}