Adding support for pre-scanning POMs for build extensions. NOTE: Plugins-as-extensions is not yet supported in this way.

git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@497993 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
John Dennis Casey 2007-01-19 22:55:19 +00:00
parent dfc4a10c68
commit dee7f572c1
5 changed files with 229 additions and 85 deletions

View File

@ -18,6 +18,7 @@ package org.apache.maven;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.context.BuildContextManager;
@ -30,7 +31,11 @@ import org.apache.maven.execution.MavenExecutionResult;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.execution.ReactorManager;
import org.apache.maven.execution.RuntimeInformation;
import org.apache.maven.extension.ExtensionManager;
import org.apache.maven.lifecycle.LifecycleExecutor;
import org.apache.maven.model.Build;
import org.apache.maven.model.Extension;
import org.apache.maven.model.Model;
import org.apache.maven.monitor.event.DefaultEventDispatcher;
import org.apache.maven.monitor.event.EventDispatcher;
import org.apache.maven.monitor.event.MavenEvents;
@ -41,11 +46,15 @@ import org.apache.maven.project.DuplicateProjectException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.project.build.model.ModelLineage;
import org.apache.maven.project.build.model.ModelLineageBuilder;
import org.apache.maven.project.build.model.ModelLineageIterator;
import org.apache.maven.reactor.MavenExecutionException;
import org.apache.maven.settings.Settings;
import org.apache.maven.usability.diagnostics.ErrorDiagnostics;
import org.codehaus.plexus.PlexusConstants;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.PlexusContainerException;
import org.codehaus.plexus.context.Context;
import org.codehaus.plexus.context.ContextException;
import org.codehaus.plexus.logging.AbstractLogEnabled;
@ -60,8 +69,10 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
/**
@ -77,6 +88,10 @@ public class DefaultMaven
// Components
// ----------------------------------------------------------------------
protected ExtensionManager extensionManager;
protected ModelLineageBuilder modelLineageBuilder;
protected BuildContextManager buildContextManager;
protected MavenProjectBuilder projectBuilder;
@ -337,6 +352,8 @@ public class DefaultMaven
throw new MavenExecutionException( "Error selecting project files for the reactor: " + e.getMessage(), e );
}
scanProjectsForExtensions( files, request, globalProfileManager );
try
{
projects = collectProjects( files, request.getLocalRepository(), request.isRecursive(),
@ -358,6 +375,91 @@ public class DefaultMaven
return projects;
}
// TODO: We should probably do this discovery just-in-time, if we can move to building project
// instances just-in-time.
private void scanProjectsForExtensions( List files, MavenExecutionRequest request,
ProfileManager globalProfileManager )
throws MavenExecutionException
{
MavenProject superProject;
try
{
superProject = projectBuilder.buildStandaloneSuperProject( request.getLocalRepository(),
globalProfileManager );
}
catch ( ProjectBuildingException e )
{
throw new MavenExecutionException( "Error building super-POM for retrieving the default remote repository list: " + e.getMessage(), e );
}
List originalRemoteRepositories = superProject.getRemoteArtifactRepositories();
Map cache = new HashMap();
for ( Iterator it = files.iterator(); it.hasNext(); )
{
File pom = (File) it.next();
ModelLineage lineage;
try
{
lineage = modelLineageBuilder.buildModelLineage( pom, request.getLocalRepository(), originalRemoteRepositories, globalProfileManager, cache );
}
catch ( ProjectBuildingException e )
{
throw new MavenExecutionException( "Error building model lineage in order to pre-scan for extensions: " + e.getMessage(), e );
}
for ( ModelLineageIterator lineageIterator = lineage.lineageIterator(); lineageIterator.hasNext(); )
{
Model model = (Model) lineageIterator.next();
Build build = model.getBuild();
if ( build != null )
{
List extensions = build.getExtensions();
if ( extensions != null && !extensions.isEmpty() )
{
List remoteRepositories = lineageIterator.getArtifactRepositories();
// thankfully, we don't have to deal with dependencyManagement here, yet.
// TODO Revisit if/when extensions are made to use the info in dependencyManagement
for ( Iterator extensionIterator = extensions.iterator(); extensionIterator.hasNext(); )
{
Extension extension = (Extension) extensionIterator.next();
try
{
extensionManager.addExtension( extension, model, remoteRepositories, request.getLocalRepository() );
}
catch ( ArtifactResolutionException e )
{
throw new MavenExecutionException( "Cannot resolve pre-scanned extension artifact: "
+ extension.getGroupId() + ":" + extension.getArtifactId() + ": " + e.getMessage(),
e );
}
catch ( ArtifactNotFoundException e )
{
throw new MavenExecutionException( "Cannot find pre-scanned extension artifact: "
+ extension.getGroupId() + ":" + extension.getArtifactId() + ": " + e.getMessage(),
e );
}
catch ( PlexusContainerException e )
{
throw new MavenExecutionException( "Failed to add pre-scanned extension: "
+ extension.getGroupId() + ":" + extension.getArtifactId() + ": " + e.getMessage(),
e );
}
}
}
}
}
}
extensionManager.registerWagons();
}
private void logReactorSummaryLine( String name,
String status )
{

View File

@ -19,6 +19,7 @@ package org.apache.maven.extension;
import org.apache.maven.ArtifactFilterManager;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.ArtifactUtils;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.manager.WagonManager;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.repository.ArtifactRepository;
@ -28,6 +29,8 @@ import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import org.apache.maven.model.Extension;
import org.apache.maven.model.Model;
import org.apache.maven.model.Parent;
import org.apache.maven.project.MavenProject;
import org.apache.maven.wagon.Wagon;
import org.codehaus.plexus.PlexusConstants;
@ -41,6 +44,7 @@ import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
@ -55,6 +59,8 @@ public class DefaultExtensionManager
implements ExtensionManager, Contextualizable
{
private ArtifactFactory artifactFactory;
private ArtifactResolver artifactResolver;
private ArtifactMetadataSource artifactMetadataSource;
@ -65,6 +71,33 @@ public class DefaultExtensionManager
private WagonManager wagonManager;
public void addExtension( Extension extension, Model originatingModel, List remoteRepositories,
ArtifactRepository localRepository )
throws ArtifactResolutionException, PlexusContainerException, ArtifactNotFoundException
{
Artifact extensionArtifact = artifactFactory.createBuildArtifact( extension.getGroupId(), extension.getArtifactId(), extension.getVersion(), "jar" );
Parent originatingParent = originatingModel.getParent();
String groupId = originatingModel.getGroupId();
if ( groupId == null && originatingParent != null )
{
groupId = originatingParent.getGroupId();
}
String artifactId = originatingModel.getArtifactId();
String version = originatingModel.getVersion();
if ( version == null && originatingParent != null )
{
version = originatingParent.getVersion();
}
Artifact projectArtifact = artifactFactory.createProjectArtifact( groupId, artifactId, version );
addExtension( extensionArtifact, projectArtifact, remoteRepositories, localRepository, null );
}
public void addExtension( Extension extension, MavenProject project, ArtifactRepository localRepository )
throws ArtifactResolutionException, PlexusContainerException, ArtifactNotFoundException
{
@ -74,21 +107,32 @@ public class DefaultExtensionManager
Artifact artifact = (Artifact) project.getExtensionArtifactMap().get( extensionId );
if ( artifact != null )
{
ArtifactFilter filter = new ProjectArtifactExceptionFilter( artifactFilterManager.getArtifactFilter(), project.getArtifact() );
addExtension( artifact, project.getArtifact(), project.getRemoteArtifactRepositories(), localRepository,
new ActiveArtifactResolver( project ) );
}
ArtifactResolutionResult result = artifactResolver.resolveTransitively( Collections.singleton( artifact ),
project.getArtifact(),
private void addExtension( Artifact extensionArtifact, Artifact projectArtifact, List remoteRepositories,
ArtifactRepository localRepository, ActiveArtifactResolver activeArtifactResolver )
throws ArtifactResolutionException, PlexusContainerException, ArtifactNotFoundException
{
if ( extensionArtifact != null )
{
ArtifactFilter filter = new ProjectArtifactExceptionFilter( artifactFilterManager.getArtifactFilter(), projectArtifact );
ArtifactResolutionResult result = artifactResolver.resolveTransitively( Collections.singleton( extensionArtifact ),
projectArtifact,
localRepository,
project.getRemoteArtifactRepositories(),
remoteRepositories,
artifactMetadataSource, filter );
for ( Iterator i = result.getArtifacts().iterator(); i.hasNext(); )
{
Artifact a = (Artifact) i.next();
a = project.replaceWithActiveArtifact( a );
if ( activeArtifactResolver != null )
{
a = activeArtifactResolver.replaceWithActiveArtifact( a );
}
getLogger().debug( "Adding to extension classpath: " + a.getFile() );
@ -117,6 +161,21 @@ public class DefaultExtensionManager
this.container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
}
private static final class ActiveArtifactResolver
{
private MavenProject project;
ActiveArtifactResolver( MavenProject project )
{
this.project = project;
}
Artifact replaceWithActiveArtifact( Artifact artifact )
{
return project.replaceWithActiveArtifact( artifact );
}
}
private static final class ProjectArtifactExceptionFilter
implements ArtifactFilter
{
@ -137,4 +196,5 @@ public class DefaultExtensionManager
return projectDependencyConflictId.equals( depConflictId ) || passThroughFilter.include( artifact );
}
}
}

View File

@ -20,9 +20,12 @@ import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.model.Extension;
import org.apache.maven.model.Model;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.PlexusContainerException;
import java.util.List;
/**
* Used to locate extensions.
*
@ -35,4 +38,8 @@ public interface ExtensionManager
throws ArtifactResolutionException, PlexusContainerException, ArtifactNotFoundException;
void registerWagons();
void addExtension( Extension extension, Model originatingModel, List remoteRepositories,
ArtifactRepository localRepository )
throws ArtifactResolutionException, PlexusContainerException, ArtifactNotFoundException;
}

View File

@ -24,9 +24,7 @@ import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.execution.ReactorManager;
import org.apache.maven.extension.ExtensionManager;
import org.apache.maven.lifecycle.mapping.LifecycleMapping;
import org.apache.maven.model.Extension;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.PluginExecution;
import org.apache.maven.model.ReportPlugin;
@ -51,7 +49,6 @@ import org.apache.maven.project.MavenProject;
import org.apache.maven.project.artifact.InvalidDependencyVersionException;
import org.apache.maven.reporting.MavenReport;
import org.apache.maven.settings.Settings;
import org.codehaus.plexus.PlexusContainerException;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.util.StringUtils;
@ -85,8 +82,6 @@ public class DefaultLifecycleExecutor
private PluginManager pluginManager;
private ExtensionManager extensionManager;
private List lifecycles;
private ArtifactHandlerManager artifactHandlerManager;
@ -134,44 +129,9 @@ public class DefaultLifecycleExecutor
List taskSegments = segmentTaskListByAggregationNeeds( goals, session, rootProject );
// TODO: probably don't want to do all this up front
findExtensions( session );
executeTaskSegments( taskSegments, rm, session, rootProject, dispatcher );
}
private void findExtensions( MavenSession session )
throws LifecycleExecutionException
{
for ( Iterator i = session.getSortedProjects().iterator(); i.hasNext(); )
{
MavenProject project = (MavenProject) i.next();
for ( Iterator j = project.getBuildExtensions().iterator(); j.hasNext(); )
{
Extension extension = (Extension) j.next();
try
{
extensionManager.addExtension( extension, project, session.getLocalRepository() );
}
catch ( PlexusContainerException e )
{
throw new LifecycleExecutionException( "Unable to initialise extensions", e );
}
catch ( ArtifactResolutionException e )
{
throw new LifecycleExecutionException( e.getMessage(), e );
}
catch ( ArtifactNotFoundException e )
{
throw new LifecycleExecutionException( e.getMessage(), e );
}
}
extensionManager.registerWagons();
try
{
Map handlers = findArtifactTypeHandlers( project, session );
Map handlers = findArtifactTypeHandlers( session );
artifactHandlerManager.addHandlers( handlers );
}
@ -179,7 +139,8 @@ public class DefaultLifecycleExecutor
{
throw new LifecycleExecutionException( e.getMessage(), e );
}
}
executeTaskSegments( taskSegments, rm, session, rootProject, dispatcher );
}
private void executeTaskSegments( List taskSegments, ReactorManager rm, MavenSession session,
@ -1154,11 +1115,17 @@ public class DefaultLifecycleExecutor
/**
* @todo Not particularly happy about this. Would like WagonManager and ArtifactTypeHandlerManager to be able to
* lookup directly, or have them passed in
*
* @todo Move this sort of thing to the tail end of the project-building process
*/
private Map findArtifactTypeHandlers( MavenProject project, MavenSession session )
private Map findArtifactTypeHandlers( MavenSession session )
throws LifecycleExecutionException, PluginNotFoundException
{
Map map = new HashMap();
for ( Iterator projectIterator = session.getSortedProjects().iterator(); projectIterator.hasNext(); )
{
MavenProject project = (MavenProject) projectIterator.next();
for ( Iterator i = project.getBuildPlugins().iterator(); i.hasNext(); )
{
Plugin plugin = (Plugin) i.next();
@ -1194,6 +1161,7 @@ public class DefaultLifecycleExecutor
}
}
}
}
return map;
}

View File

@ -48,6 +48,9 @@
<requirement>
<role>org.apache.maven.ArtifactFilterManager</role>
</requirement>
<requirement>
<role>org.apache.maven.artifact.factory.ArtifactFactory</role>
</requirement>
<requirement>
<role>org.apache.maven.artifact.resolver.ArtifactResolver</role>
</requirement>
@ -80,6 +83,13 @@
<role>org.apache.maven.Maven</role>
<implementation>org.apache.maven.DefaultMaven</implementation>
<requirements>
<requirement>
<role>org.apache.maven.extension.ExtensionManager</role>
</requirement>
<requirement>
<role>org.apache.maven.project.build.model.ModelLineageBuilder</role>
<role-hint>default</role-hint>
</requirement>
<requirement>
<role>org.apache.maven.context.BuildContextManager</role>
<role-hint>default</role-hint>
@ -206,9 +216,6 @@
<requirement>
<role>org.apache.maven.plugin.PluginManager</role>
</requirement>
<requirement>
<role>org.apache.maven.extension.ExtensionManager</role>
</requirement>
<requirement>
<role>org.apache.maven.artifact.handler.manager.ArtifactHandlerManager</role>
</requirement>