Refactor the artifact-scanning logic from the realm manager and the plugin-artifact resolution logic in the plugin manager into two separate classes, one a component and one a static class, to allow the new PluginPrefixLoader to reuse some of both and create a lighter-weight approach to grabbing the PluginDescriptor for build-planning purposes...also avoids some needless error messages during build planning.

git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@617293 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
John Dennis Casey 2008-01-31 23:29:18 +00:00
parent e670bd3ea3
commit f838337b7a
12 changed files with 734 additions and 371 deletions

View File

@ -14,6 +14,7 @@ import org.apache.maven.plugin.version.PluginVersionNotFoundException;
import org.apache.maven.plugin.version.PluginVersionResolutionException;
import org.apache.maven.plugin.InvalidPluginException;
import org.apache.maven.plugin.PluginManager;
import org.apache.maven.plugin.PluginManagerSupport;
import org.apache.maven.plugin.PluginManagerException;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.model.Model;
@ -215,7 +216,7 @@ public privileged aspect ExtensionErrorReporterAspect
cflow( dem_addPluginAsExtension( Plugin, originModel, remoteRepos, request ) )
&& cflow( execution( * PluginManager+.verifyPlugin( .. ) ) )
&& cflow( dpm_verifyVersionedPlugin( plugin ) )
&& call( private void DefaultPluginManager.checkRequiredMavenVersion( .. ) )
&& call( void PluginManagerSupport+.checkRequiredMavenVersion( .. ) )
{
getReporter().reportIncompatibleMavenVersionForExtensionPlugin( plugin, originModel, remoteRepos, request, requiredVersion, currentVersion, err );
}

View File

@ -4,9 +4,10 @@ import org.apache.maven.execution.MavenSession;
import org.apache.maven.lifecycle.LifecycleLoaderException;
import org.apache.maven.lifecycle.LifecycleSpecificationException;
import org.apache.maven.lifecycle.model.MojoBinding;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.loader.PluginLoader;
import org.apache.maven.plugin.loader.PluginLoaderException;
import org.apache.maven.plugin.loader.PluginPrefixLoader;
import org.apache.maven.project.MavenProject;
import java.util.StringTokenizer;
@ -22,7 +23,7 @@ public class DefaultMojoBindingFactory
implements MojoBindingFactory
{
PluginLoader pluginLoader;
PluginPrefixLoader pluginPrefixLoader;
/**
* Parse the specified mojo string into a MojoBinding, optionally allowing plugin-prefix references.
@ -49,10 +50,10 @@ public class DefaultMojoBindingFactory
String prefix = tok.nextToken();
PluginDescriptor pluginDescriptor;
Plugin plugin;
try
{
pluginDescriptor = pluginLoader.findPluginForPrefix( prefix, project, session );
plugin = pluginPrefixLoader.findPluginForPrefix( prefix, project, session );
}
catch ( PluginLoaderException e )
{
@ -61,8 +62,8 @@ public class DefaultMojoBindingFactory
e );
}
binding = createMojoBinding( pluginDescriptor.getGroupId(), pluginDescriptor.getArtifactId(),
pluginDescriptor.getVersion(), tok.nextToken(), project );
binding = createMojoBinding( plugin.getGroupId(), plugin.getArtifactId(),
plugin.getVersion(), tok.nextToken(), project );
}
else if ( ( numTokens == 3 ) || ( numTokens == 4 ) )
{

View File

@ -53,7 +53,6 @@ import org.apache.maven.plugin.version.PluginVersionNotFoundException;
import org.apache.maven.plugin.version.PluginVersionResolutionException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.project.artifact.InvalidDependencyVersionException;
import org.apache.maven.project.artifact.MavenMetadataSource;
import org.apache.maven.project.path.PathTranslator;
@ -133,6 +132,8 @@ public class DefaultPluginManager
protected PluginMappingManager pluginMappingManager;
private PluginManagerSupport pluginManagerSupport;
// END component requirements
public DefaultPluginManager()
@ -201,37 +202,7 @@ public class DefaultPluginManager
// if the groupId is internal, don't try to resolve it...
if ( !RESERVED_GROUP_IDS.contains( plugin.getGroupId() ) )
{
VersionRange versionRange;
try
{
versionRange = VersionRange.createFromVersionSpec( plugin.getVersion() );
}
catch ( InvalidVersionSpecificationException e )
{
throw new PluginManagerException( plugin, e );
}
List remoteRepositories = new ArrayList();
// remoteRepositories.addAll( project.getPluginArtifactRepositories() );
remoteRepositories.addAll( project.getRemoteArtifactRepositories() );
MavenProject pluginProject = buildPluginProject( plugin, localRepository, remoteRepositories );
checkRequiredMavenVersion( plugin, pluginProject, localRepository, remoteRepositories );
checkPluginDependencySpec( plugin, pluginProject );
Artifact pluginArtifact = artifactFactory.createPluginArtifact(
plugin.getGroupId(),
plugin.getArtifactId(),
versionRange );
pluginArtifact = project.replaceWithActiveArtifact( pluginArtifact );
artifactResolver.resolve( pluginArtifact, project.getRemoteArtifactRepositories(),
localRepository );
Artifact pluginArtifact = pluginManagerSupport.resolvePluginArtifact( plugin, project, session );
addPlugin( plugin, pluginArtifact, project, session );
}
@ -274,70 +245,6 @@ public class DefaultPluginManager
return pluginDescriptor;
}
private void checkPluginDependencySpec( Plugin plugin,
MavenProject pluginProject )
throws InvalidPluginException
{
ArtifactFilter filter = new ScopeArtifactFilter( "runtime" );
try
{
pluginProject.createArtifacts( artifactFactory, null, filter );
}
catch ( InvalidDependencyVersionException e )
{
throw new InvalidPluginException( "Plugin: " + plugin.getKey() + " has a dependency with an invalid version.", e );
}
}
private MavenProject buildPluginProject( Plugin plugin,
ArtifactRepository localRepository,
List remoteRepositories )
throws InvalidPluginException
{
Artifact artifact = artifactFactory.createProjectArtifact( plugin.getGroupId(),
plugin.getArtifactId(),
plugin.getVersion() );
try
{
return mavenProjectBuilder.buildFromRepository( artifact,
remoteRepositories,
localRepository );
}
catch ( ProjectBuildingException e )
{
throw new InvalidPluginException( "Unable to build project for plugin '"
+ plugin.getKey() + "': " + e.getMessage(), e );
}
}
/**
* @param pluginProject
* @todo would be better to store this in the plugin descriptor, but then it won't be available to the version
* manager which executes before the plugin is instantiated
*/
private void checkRequiredMavenVersion( Plugin plugin,
MavenProject pluginProject,
ArtifactRepository localRepository,
List remoteRepositories )
throws PluginVersionResolutionException, InvalidPluginException
{
// if we don't have the required Maven version, then ignore an update
if ( ( pluginProject.getPrerequisites() != null )
&& ( pluginProject.getPrerequisites().getMaven() != null ) )
{
DefaultArtifactVersion requiredVersion = new DefaultArtifactVersion( pluginProject.getPrerequisites().getMaven() );
if ( runtimeInformation.getApplicationVersion().compareTo( requiredVersion ) < 0 )
{
throw new PluginVersionResolutionException( plugin.getGroupId(),
plugin.getArtifactId(),
"Plugin requires Maven version "
+ requiredVersion );
}
}
}
protected void addPlugin( Plugin plugin,
Artifact pluginArtifact,
MavenProject project,

View File

@ -0,0 +1,262 @@
package org.apache.maven.plugin;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
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.resolver.ArtifactResolver;
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.execution.RuntimeInformation;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.version.PluginVersionManager;
import org.apache.maven.plugin.version.PluginVersionNotFoundException;
import org.apache.maven.plugin.version.PluginVersionResolutionException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.project.artifact.InvalidDependencyVersionException;
import org.apache.maven.realm.RealmManagementException;
import org.apache.maven.realm.RealmScanningUtils;
import org.codehaus.plexus.context.Context;
import org.codehaus.plexus.context.ContextException;
import org.codehaus.plexus.logging.LogEnabled;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
import java.util.ArrayList;
import java.util.List;
public class DefaultPluginManagerSupport
implements PluginManagerSupport, LogEnabled, Contextualizable
{
private ArtifactResolver artifactResolver;
private ArtifactFactory artifactFactory;
private MavenProjectBuilder mavenProjectBuilder;
private RuntimeInformation runtimeInformation;
private PluginVersionManager pluginVersionManager;
private Logger logger;
private Context containerContext;
public Artifact resolvePluginArtifact( Plugin plugin,
MavenProject project,
MavenSession session )
throws PluginManagerException, InvalidPluginException, PluginVersionResolutionException,
ArtifactResolutionException, ArtifactNotFoundException
{
ArtifactRepository localRepository = session.getLocalRepository();
VersionRange versionRange;
try
{
versionRange = VersionRange.createFromVersionSpec( plugin.getVersion() );
}
catch ( InvalidVersionSpecificationException e )
{
throw new PluginManagerException( plugin, e );
}
List remoteRepositories = new ArrayList();
// remoteRepositories.addAll( project.getPluginArtifactRepositories() );
remoteRepositories.addAll( project.getRemoteArtifactRepositories() );
MavenProject pluginProject = buildPluginProject( plugin,
localRepository,
remoteRepositories );
checkRequiredMavenVersion( plugin, pluginProject, localRepository, remoteRepositories );
checkPluginDependencySpec( plugin, pluginProject );
Artifact pluginArtifact = artifactFactory.createPluginArtifact( plugin.getGroupId(),
plugin.getArtifactId(),
versionRange );
pluginArtifact = project.replaceWithActiveArtifact( pluginArtifact );
artifactResolver.resolve( pluginArtifact, remoteRepositories, localRepository );
return pluginArtifact;
}
public MavenProject buildPluginProject( Plugin plugin,
ArtifactRepository localRepository,
List remoteRepositories )
throws InvalidPluginException
{
Artifact artifact = artifactFactory.createProjectArtifact( plugin.getGroupId(),
plugin.getArtifactId(),
plugin.getVersion() );
try
{
return mavenProjectBuilder.buildFromRepository( artifact,
remoteRepositories,
localRepository );
}
catch ( ProjectBuildingException e )
{
throw new InvalidPluginException( "Unable to build project for plugin '"
+ plugin.getKey() + "': " + e.getMessage(), e );
}
}
/**
* @param pluginProject
* @todo would be better to store this in the plugin descriptor, but then it won't be available to the version
* manager which executes before the plugin is instantiated
*/
public void checkRequiredMavenVersion( Plugin plugin,
MavenProject pluginProject,
ArtifactRepository localRepository,
List remoteRepositories )
throws PluginVersionResolutionException, InvalidPluginException
{
// if we don't have the required Maven version, then ignore an update
if ( ( pluginProject.getPrerequisites() != null )
&& ( pluginProject.getPrerequisites().getMaven() != null ) )
{
DefaultArtifactVersion requiredVersion = new DefaultArtifactVersion(
pluginProject.getPrerequisites()
.getMaven() );
if ( runtimeInformation.getApplicationVersion().compareTo( requiredVersion ) < 0 )
{
throw new PluginVersionResolutionException( plugin.getGroupId(),
plugin.getArtifactId(),
"Plugin requires Maven version "
+ requiredVersion );
}
}
}
public void checkPluginDependencySpec( Plugin plugin,
MavenProject pluginProject )
throws InvalidPluginException
{
ArtifactFilter filter = new ScopeArtifactFilter( "runtime" );
try
{
pluginProject.createArtifacts( artifactFactory, null, filter );
}
catch ( InvalidDependencyVersionException e )
{
throw new InvalidPluginException( "Plugin: " + plugin.getKey()
+ " has a dependency with an invalid version.", e );
}
}
public PluginDescriptor loadIsolatedPluginDescriptor( Plugin plugin,
MavenProject project,
MavenSession session )
{
if ( plugin.getVersion() == null )
{
try
{
plugin.setVersion( pluginVersionManager.resolvePluginVersion( plugin.getGroupId(),
plugin.getArtifactId(),
project,
session ) );
}
catch ( PluginVersionResolutionException e )
{
logger.debug( "Failed to load plugin descriptor for: " + plugin.getKey(), e );
}
catch ( InvalidPluginException e )
{
logger.debug( "Failed to load plugin descriptor for: " + plugin.getKey(), e );
}
catch ( PluginVersionNotFoundException e )
{
logger.debug( "Failed to load plugin descriptor for: " + plugin.getKey(), e );
}
}
if ( plugin.getVersion() == null )
{
return null;
}
Artifact artifact = null;
try
{
artifact = resolvePluginArtifact( plugin, project, session );
}
catch ( ArtifactResolutionException e )
{
logger.debug( "Failed to load plugin descriptor for: " + plugin.getKey(), e );
}
catch ( ArtifactNotFoundException e )
{
logger.debug( "Failed to load plugin descriptor for: " + plugin.getKey(), e );
}
catch ( PluginManagerException e )
{
logger.debug( "Failed to load plugin descriptor for: " + plugin.getKey(), e );
}
catch ( InvalidPluginException e )
{
logger.debug( "Failed to load plugin descriptor for: " + plugin.getKey(), e );
}
catch ( PluginVersionResolutionException e )
{
logger.debug( "Failed to load plugin descriptor for: " + plugin.getKey(), e );
}
if ( artifact == null )
{
return null;
}
MavenPluginDiscoverer discoverer = new MavenPluginDiscoverer();
discoverer.setManager( RealmScanningUtils.getDummyComponentDiscovererManager() );
try
{
List componentSetDescriptors = RealmScanningUtils.scanForComponentSetDescriptors( artifact,
discoverer,
containerContext,
"Plugin: "
+ plugin.getKey() );
if ( !componentSetDescriptors.isEmpty() )
{
return (PluginDescriptor) componentSetDescriptors.get( 0 );
}
}
catch ( RealmManagementException e )
{
logger.debug( "Failed to scan plugin artifact: " + artifact.getId()
+ " for descriptors.", e );
}
return null;
}
public void enableLogging( Logger logger )
{
this.logger = logger;
}
public void contextualize( Context context )
throws ContextException
{
containerContext = context;
}
}

View File

@ -0,0 +1,48 @@
package org.apache.maven.plugin;
import org.apache.maven.artifact.Artifact;
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.execution.MavenSession;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.version.PluginVersionResolutionException;
import org.apache.maven.project.MavenProject;
import java.util.List;
public interface PluginManagerSupport
{
Artifact resolvePluginArtifact( Plugin plugin,
MavenProject project,
MavenSession session )
throws PluginManagerException, InvalidPluginException, PluginVersionResolutionException,
ArtifactResolutionException, ArtifactNotFoundException;
MavenProject buildPluginProject( Plugin plugin,
ArtifactRepository localRepository,
List remoteRepositories )
throws InvalidPluginException;
/**
* @param pluginProject
* @todo would be better to store this in the plugin descriptor, but then it won't be available to the version
* manager which executes before the plugin is instantiated
*/
void checkRequiredMavenVersion( Plugin plugin,
MavenProject pluginProject,
ArtifactRepository localRepository,
List remoteRepositories )
throws PluginVersionResolutionException, InvalidPluginException;
void checkPluginDependencySpec( Plugin plugin,
MavenProject pluginProject )
throws InvalidPluginException;
PluginDescriptor loadIsolatedPluginDescriptor( Plugin plugin,
MavenProject project,
MavenSession session );
}

View File

@ -8,23 +8,16 @@ import org.apache.maven.lifecycle.model.MojoBinding;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.ReportPlugin;
import org.apache.maven.plugin.InvalidPluginException;
import org.apache.maven.plugin.MavenPluginCollector;
import org.apache.maven.plugin.PluginManager;
import org.apache.maven.plugin.PluginManagerException;
import org.apache.maven.plugin.PluginMappingManager;
import org.apache.maven.plugin.PluginNotFoundException;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.version.PluginVersionNotFoundException;
import org.apache.maven.plugin.version.PluginVersionResolutionException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Settings;
import org.codehaus.plexus.logging.LogEnabled;
import org.codehaus.plexus.logging.Logger;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* Responsible for loading plugins, reports, and any components contained therein. Will resolve
* plugin versions and plugin prefixes as necessary for plugin resolution.
@ -41,10 +34,6 @@ public class DefaultPluginLoader
// FIXME: Move the functionality used from this into the PluginLoader when PluginManager refactor is complete.
private PluginManager pluginManager;
private PluginMappingManager pluginMappingManager;
private MavenPluginCollector pluginCollector;
/**
* Load the {@link PluginDescriptor} instance for the plugin implied by the specified MojoBinding,
* using the project for {@link ArtifactRepository} and other supplemental plugin information as
@ -73,117 +62,6 @@ public class DefaultPluginLoader
return pluginDescriptor;
}
/**
* Determine the appropriate {@link PluginDescriptor} instance for use with the specified plugin
* prefix, using the following strategies (in order):
* <br/>
* <ol>
* <li>Search for a plugin that has already been loaded with the specified prefix</li>
* <li>Search for a plugin configured in the POM that has a matching prefix</li>
* <li>Search the pluginGroups specified in the settings.xml for a matching plugin</li>
* <li>Use groupId == org.apache.maven.plugins, and artifactId == maven-&lt;prefix&gt;-plugin,
* and try to resolve based on that.</li>
* </ol>
*/
public PluginDescriptor findPluginForPrefix( String prefix, MavenProject project, MavenSession session )
throws PluginLoaderException
{
Set descriptors = pluginCollector.getPluginDescriptorsForPrefix( prefix );
Map projectPluginMap = project.getBuild().getPluginsAsMap();
PluginDescriptor pluginDescriptor = null;
if ( descriptors != null )
{
for ( Iterator it = descriptors.iterator(); it.hasNext(); )
{
PluginDescriptor pd = (PluginDescriptor) it.next();
Plugin projectPlugin = (Plugin) projectPluginMap.get( pd.getPluginLookupKey() );
if ( ( projectPlugin != null ) && ( projectPlugin.getVersion() != null ) && projectPlugin.getVersion().equals( pd.getVersion() ) )
{
pluginDescriptor = pd;
break;
}
}
}
if ( pluginDescriptor == null )
{
pluginDescriptor = loadFromProject( prefix, project, session );
}
if ( pluginDescriptor == null )
{
pluginDescriptor = loadByPrefix( prefix, project, session );
}
if ( pluginDescriptor == null )
{
Plugin plugin = new Plugin();
plugin.setArtifactId( PluginDescriptor.getDefaultPluginArtifactId( prefix ) );
pluginDescriptor = loadPlugin( plugin, project, session );
}
if ( pluginDescriptor == null )
{
throw new PluginLoaderException( "Cannot find plugin with prefix: " + prefix );
}
return pluginDescriptor;
}
/**
* Look for a plugin configured in the current project that has a prefix matching the one
* specified. Return the {@link PluginDescriptor} if a match is found.
*/
private PluginDescriptor loadFromProject( String prefix, MavenProject project, MavenSession session )
throws PluginLoaderException
{
PluginDescriptor result = null;
for ( Iterator it = project.getBuildPlugins().iterator(); it.hasNext(); )
{
Plugin plugin = (Plugin) it.next();
PluginDescriptor pluginDescriptor = loadPlugin( plugin, project, session );
if ( prefix.equals( pluginDescriptor.getGoalPrefix() ) )
{
result = pluginDescriptor;
break;
}
}
return result;
}
/**
* Look for a plugin in the pluginGroups specified in the settings.xml that has a prefix
* matching the one specified. Return the {@link PluginDescriptor} if a match is found.
*/
private PluginDescriptor loadByPrefix( String prefix, MavenProject project, MavenSession session )
throws PluginLoaderException
{
Settings settings = session.getSettings();
Plugin plugin = pluginMappingManager.getByPrefix( prefix, settings.getPluginGroups(),
project.getRemoteArtifactRepositories(), session.getLocalRepository() );
PluginDescriptor pluginDescriptor = null;
if ( plugin != null )
{
Plugin projectPlugin = (Plugin) project.getBuild().getPluginsAsMap().get( plugin.getKey() );
if ( ( projectPlugin != null ) && ( projectPlugin.getVersion() != null ) )
{
plugin.setVersion( projectPlugin.getVersion() );
}
pluginDescriptor = loadPlugin( plugin, project, session );
}
return pluginDescriptor;
}
/**
* Load the {@link PluginDescriptor} instance for the specified plugin, using the project for
* the {@link ArtifactRepository} and other supplemental plugin information as necessary.

View File

@ -0,0 +1,182 @@
package org.apache.maven.plugin.loader;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.MavenPluginCollector;
import org.apache.maven.plugin.PluginManagerSupport;
import org.apache.maven.plugin.PluginMappingManager;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Settings;
import org.codehaus.plexus.logging.LogEnabled;
import org.codehaus.plexus.logging.Logger;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class DefaultPluginPrefixLoader
implements PluginPrefixLoader, LogEnabled
{
private Logger logger;
private PluginMappingManager pluginMappingManager;
private MavenPluginCollector pluginCollector;
private PluginManagerSupport pluginManagerSupport;
/**
* Determine the appropriate {@link PluginDescriptor} instance for use with the specified plugin
* prefix, using the following strategies (in order):
* <br/>
* <ol>
* <li>Search for a plugin that has already been loaded with the specified prefix</li>
* <li>Search for a plugin configured in the POM that has a matching prefix</li>
* <li>Search the pluginGroups specified in the settings.xml for a matching plugin</li>
* <li>Use groupId == org.apache.maven.plugins, and artifactId == maven-&lt;prefix&gt;-plugin,
* and try to resolve based on that.</li>
* </ol>
*/
public Plugin findPluginForPrefix( String prefix,
MavenProject project,
MavenSession session )
throws PluginLoaderException
{
Set descriptors = pluginCollector.getPluginDescriptorsForPrefix( prefix );
Map projectPluginMap = project.getBuild().getPluginsAsMap();
Plugin plugin = null;
if ( descriptors != null )
{
PluginDescriptor pluginDescriptor = null;
for ( Iterator it = descriptors.iterator(); it.hasNext(); )
{
PluginDescriptor pd = (PluginDescriptor) it.next();
Plugin projectPlugin = (Plugin) projectPluginMap.get( pd.getPluginLookupKey() );
if ( ( projectPlugin != null ) && ( projectPlugin.getVersion() != null )
&& projectPlugin.getVersion().equals( pd.getVersion() ) )
{
pluginDescriptor = pd;
break;
}
}
plugin = toPlugin( pluginDescriptor );
}
if ( plugin == null )
{
PluginDescriptor pluginDescriptor = loadFromProjectForPrefixQuery( prefix, project, session );
plugin = toPlugin( pluginDescriptor );
}
if ( plugin == null )
{
plugin = loadFromPrefixMapper( prefix, project, session );
}
if ( plugin == null )
{
plugin = new Plugin();
plugin.setArtifactId( PluginDescriptor.getDefaultPluginArtifactId( prefix ) );
PluginDescriptor pluginDescriptor = pluginManagerSupport.loadIsolatedPluginDescriptor( plugin,
project,
session );
plugin = toPlugin( pluginDescriptor );
}
if ( plugin == null )
{
throw new PluginLoaderException( "Cannot find plugin with prefix: " + prefix );
}
return plugin;
}
private Plugin toPlugin( PluginDescriptor pluginDescriptor )
{
if ( pluginDescriptor == null )
{
return null;
}
Plugin plugin = new Plugin();
plugin.setGroupId( pluginDescriptor.getGroupId() );
plugin.setArtifactId( pluginDescriptor.getArtifactId() );
plugin.setVersion( pluginDescriptor.getVersion() );
return plugin;
}
/**
* Look for a plugin configured in the current project that has a prefix matching the one
* specified. Return the {@link PluginDescriptor} if a match is found.
*/
private PluginDescriptor loadFromProjectForPrefixQuery( String prefix,
MavenProject project,
MavenSession session )
throws PluginLoaderException
{
PluginDescriptor result = null;
for ( Iterator it = project.getBuildPlugins().iterator(); it.hasNext(); )
{
Plugin plugin = (Plugin) it.next();
PluginDescriptor pluginDescriptor = pluginManagerSupport.loadIsolatedPluginDescriptor( plugin,
project,
session );
if ( ( pluginDescriptor != null ) && prefix.equals( pluginDescriptor.getGoalPrefix() ) )
{
result = pluginDescriptor;
break;
}
}
return result;
}
/**
* Look for a plugin in the pluginGroups specified in the settings.xml that has a prefix
* matching the one specified. Return the {@link PluginDescriptor} if a match is found.
*/
private Plugin loadFromPrefixMapper( String prefix,
MavenProject project,
MavenSession session )
throws PluginLoaderException
{
Settings settings = session.getSettings();
Plugin plugin = pluginMappingManager.getByPrefix( prefix,
settings.getPluginGroups(),
project.getRemoteArtifactRepositories(),
session.getLocalRepository() );
if ( plugin != null )
{
Plugin projectPlugin = (Plugin) project.getBuild().getPluginsAsMap().get( plugin.getKey() );
if ( ( projectPlugin != null ) && ( projectPlugin.getVersion() != null ) )
{
plugin.setVersion( projectPlugin.getVersion() );
}
}
return plugin;
}
public void enableLogging( Logger logger )
{
this.logger = logger;
}
}

View File

@ -48,19 +48,4 @@ public interface PluginLoader
PluginDescriptor loadReportPlugin( MojoBinding mojoBinding, MavenProject project, MavenSession session )
throws PluginLoaderException;
/**
* Determine the appropriate {@link PluginDescriptor} instance for use with the specified plugin
* prefix, using the following strategies (in order):
* <br/>
* <ol>
* <li>Search for a plugin that has already been loaded with the specified prefix</li>
* <li>Search for a plugin configured in the POM that has a matching prefix</li>
* <li>Search the pluginGroups specified in the settings.xml for a matching plugin</li>
* <li>Use groupId == org.apache.maven.plugins, and artifactId == maven-&lt;prefix&gt;-plugin,
* and try to resolve based on that.</li>
* </ol>
*/
PluginDescriptor findPluginForPrefix( String prefix, MavenProject project, MavenSession session )
throws PluginLoaderException;
}

View File

@ -0,0 +1,25 @@
package org.apache.maven.plugin.loader;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Plugin;
import org.apache.maven.project.MavenProject;
public interface PluginPrefixLoader
{
/**
* Determine the appropriate {@link Plugin} instance for use with the specified plugin
* prefix, using the following strategies (in order):
* <br/>
* <ol>
* <li>Search for a plugin that has already been loaded with the specified prefix</li>
* <li>Search for a plugin configured in the POM that has a matching prefix</li>
* <li>Search the pluginGroups specified in the settings.xml for a matching plugin</li>
* <li>Use groupId == org.apache.maven.plugins, and artifactId == maven-&lt;prefix&gt;-plugin,
* and try to resolve based on that.</li>
* </ol>
*/
Plugin findPluginForPrefix( String prefix, MavenProject project, MavenSession session )
throws PluginLoaderException;
}

View File

@ -209,6 +209,9 @@ under the License.
<role>org.apache.maven.plugin.PluginManager</role>
<implementation>org.apache.maven.plugin.DefaultPluginManager</implementation>
<requirements>
<requirement>
<role>org.apache.maven.plugin.PluginManagerSupport</role>
</requirement>
<requirement>
<role>org.apache.maven.ArtifactFilterManager</role>
</requirement>
@ -690,10 +693,21 @@ under the License.
<implementation>org.apache.maven.plugin.loader.DefaultPluginLoader</implementation>
<requirements>
<requirement>
<role>org.apache.maven.plugin.MavenPluginCollector</role>
<role>org.apache.maven.plugin.PluginManager</role>
</requirement>
</requirements>
</component>
<component>
<role>org.apache.maven.plugin.loader.PluginPrefixLoader</role>
<role-hint>default</role-hint>
<implementation>org.apache.maven.plugin.loader.DefaultPluginPrefixLoader</implementation>
<requirements>
<requirement>
<role>org.apache.maven.plugin.PluginManagerSupport</role>
</requirement>
<requirement>
<role>org.apache.maven.plugin.PluginManager</role>
<role>org.apache.maven.plugin.MavenPluginCollector</role>
</requirement>
<requirement>
<role>org.apache.maven.plugin.PluginMappingManager</role>
@ -821,7 +835,7 @@ under the License.
<implementation>org.apache.maven.lifecycle.binding.DefaultMojoBindingFactory</implementation>
<requirements>
<requirement>
<role>org.apache.maven.plugin.loader.PluginLoader</role>
<role>org.apache.maven.plugin.loader.PluginPrefixLoader</role>
</requirement>
</requirements>
</component>
@ -850,5 +864,28 @@ under the License.
</requirement>
</requirements>
</component>
<component>
<role>org.apache.maven.plugin.PluginManagerSupport</role>
<role-hint>default</role-hint>
<implementation>org.apache.maven.plugin.DefaultPluginManagerSupport</implementation>
<requirements>
<requirement>
<role>org.apache.maven.plugin.version.PluginVersionManager</role>
</requirement>
<requirement>
<role>org.apache.maven.artifact.resolver.ArtifactResolver</role>
</requirement>
<requirement>
<role>org.apache.maven.artifact.factory.ArtifactFactory</role>
</requirement>
<requirement>
<role>org.apache.maven.project.MavenProjectBuilder</role>
</requirement>
<requirement>
<role>org.apache.maven.execution.RuntimeInformation</role>
</requirement>
</requirements>
</component>
</components>
</component-set>

View File

@ -28,14 +28,10 @@ import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.classworlds.realm.DuplicateRealmException;
import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
import org.codehaus.plexus.component.discovery.ComponentDiscoverer;
import org.codehaus.plexus.component.discovery.ComponentDiscovererManager;
import org.codehaus.plexus.component.discovery.ComponentDiscoveryEvent;
import org.codehaus.plexus.component.discovery.ComponentDiscoveryListener;
import org.codehaus.plexus.component.discovery.DefaultComponentDiscoverer;
import org.codehaus.plexus.component.repository.ComponentDescriptor;
import org.codehaus.plexus.component.repository.ComponentSetDescriptor;
import org.codehaus.plexus.component.repository.exception.ComponentRepositoryException;
import org.codehaus.plexus.configuration.PlexusConfigurationException;
import org.codehaus.plexus.logging.Logger;
import java.net.MalformedURLException;
@ -152,106 +148,53 @@ public class DefaultMavenRealmManager
throw new RealmManagementException( extensionRealmId, "Cannot import project extensions; extension artifact has no associated file that can be scanned for extension components (extension: " + extensionArtifact.getId() + ")" );
}
ClassWorld discoveryWorld = new ClassWorld();
List componentSetDescriptors;
try
ComponentDiscoverer discoverer = new DefaultComponentDiscoverer();
discoverer.setManager( RealmScanningUtils.getDummyComponentDiscovererManager() );
List componentSetDescriptors = RealmScanningUtils.scanForComponentSetDescriptors( extensionArtifact, discoverer, container.getContext(), extensionRealmId );
ClassRealm realm = getProjectRealm( projectGroupId, projectArtifactId, projectVersion, true );
for ( Iterator it = componentSetDescriptors.iterator(); it.hasNext(); )
{
// Create an entire new ClassWorld, ClassRealm for discovering
// the immediate components of the extension artifact, so we don't pollute the
// container with component descriptors or realms that don't have any meaning beyond discovery.
ClassRealm discoveryRealm;
try
ComponentSetDescriptor compSet = (ComponentSetDescriptor) it.next();
for ( Iterator compIt = compSet.getComponents().iterator(); compIt.hasNext(); )
{
discoveryRealm = discoveryWorld.newRealm( "discovery: " + extensionRealmId );
}
catch ( DuplicateRealmException e )
{
throw new RealmManagementException( extensionRealmId, "Unable to create temporary ClassRealm for local-component discovery.", e );
}
// For each component in the extension artifact:
ComponentDescriptor comp = (ComponentDescriptor) compIt.next();
String implementation = comp.getImplementation();
try
{
discoveryRealm.addURL( extensionArtifact.getFile().toURL() );
}
catch ( MalformedURLException e )
{
throw new RealmManagementException( extensionRealmId, extensionArtifact, "Unable to generate URL from extension artifact file: " + extensionArtifact.getFile() + " for local-component discovery.", e );
}
ComponentDiscoverer discoverer = new DefaultComponentDiscoverer();
discoverer.setManager( new DummyDiscovererManager() );
try
{
// Find the extension component descriptors that exist ONLY in the immediate extension
// artifact...this prevents us from adding plexus-archiver components to the mix, for instance,
// when the extension uses that dependency.
componentSetDescriptors = discoverer.findComponents( container.getContext(), discoveryRealm );
}
catch ( PlexusConfigurationException e )
{
throw new RealmManagementException( extensionRealmId, "Unable to discover components in extension artifact: " + extensionArtifact.getId(), e );
}
ClassRealm realm = getProjectRealm( projectGroupId, projectArtifactId, projectVersion, true );
for ( Iterator it = componentSetDescriptors.iterator(); it.hasNext(); )
{
ComponentSetDescriptor compSet = (ComponentSetDescriptor) it.next();
for ( Iterator compIt = compSet.getComponents().iterator(); compIt.hasNext(); )
{
// For each component in the extension artifact:
ComponentDescriptor comp = (ComponentDescriptor) compIt.next();
String implementation = comp.getImplementation();
try
{
logger.debug( "Importing: " + implementation + "\nwith role: " + comp.getRole() + "\nand hint: " + comp.getRoleHint() + "\nfrom extension realm: " + extensionRealmId + "\nto project realm: " + realm.getId() );
// Import the extension component's implementation class into the project-level
// realm.
realm.importFrom( extensionRealmId, implementation );
// Set the realmId to be used in looking up this extension component to the
// project-level realm, since we now have a restricted import
// that allows most of the extension to stay hidden, and the
// specific local extension components are still accessible
// from the project-level realm.
comp.setRealmId( realm.getId() );
// Finally, add the extension component's descriptor (with projectRealm
// set as the lookup realm) to the container.
container.addComponentDescriptor( comp );
}
catch ( NoSuchRealmException e )
{
throw new RealmManagementException( extensionRealmId, "Failed to create import for component: " + implementation + " from extension realm: " + extensionRealmId + " to project realm: " + realm.getId(), e );
}
catch ( ComponentRepositoryException e )
{
String projectId = RealmUtils.createProjectId( projectGroupId, projectArtifactId, projectVersion );
throw new RealmManagementException( extensionRealmId, "Unable to discover components from imports to project: " + projectId + " from extension artifact: " + extensionArtifact.getId(), e );
}
}
}
}
finally
{
Collection realms = discoveryWorld.getRealms();
for ( Iterator it = realms.iterator(); it.hasNext(); )
{
ClassRealm realm = (ClassRealm) it.next();
try
{
discoveryWorld.disposeRealm( realm.getId() );
logger.debug( "Importing: " + implementation + "\nwith role: " + comp.getRole() + "\nand hint: " + comp.getRoleHint() + "\nfrom extension realm: " + extensionRealmId + "\nto project realm: " + realm.getId() );
// Import the extension component's implementation class into the project-level
// realm.
realm.importFrom( extensionRealmId, implementation );
// Set the realmId to be used in looking up this extension component to the
// project-level realm, since we now have a restricted import
// that allows most of the extension to stay hidden, and the
// specific local extension components are still accessible
// from the project-level realm.
comp.setRealmId( realm.getId() );
// Finally, add the extension component's descriptor (with projectRealm
// set as the lookup realm) to the container.
container.addComponentDescriptor( comp );
}
catch ( NoSuchRealmException e )
{
throw new RealmManagementException( extensionRealmId, "Failed to create import for component: " + implementation + " from extension realm: " + extensionRealmId + " to project realm: " + realm.getId(), e );
}
catch ( ComponentRepositoryException e )
{
String projectId = RealmUtils.createProjectId( projectGroupId, projectArtifactId, projectVersion );
throw new RealmManagementException( extensionRealmId, "Unable to discover components from imports to project: " + projectId + " from extension artifact: " + extensionArtifact.getId(), e );
}
}
}
}
public ClassRealm getProjectRealm( String projectGroupId, String projectArtifactId, String projectVersion )
@ -287,42 +230,6 @@ public class DefaultMavenRealmManager
return realm;
}
private static final class DummyDiscovererManager implements ComponentDiscovererManager
{
public void fireComponentDiscoveryEvent( ComponentDiscoveryEvent arg0 )
{
}
public List getComponentDiscoverers()
{
return null;
}
public Map getComponentDiscoveryListeners()
{
return null;
}
public List getListeners()
{
return null;
}
public void initialize()
{
}
public void registerComponentDiscoveryListener( ComponentDiscoveryListener l )
{
}
public void removeComponentDiscoveryListener( ComponentDiscoveryListener l )
{
}
}
public ClassRealm getPluginRealm( Plugin plugin )
{
String id = RealmUtils.createPluginRealmId( plugin );

View File

@ -0,0 +1,130 @@
package org.apache.maven.realm;
import org.apache.maven.artifact.Artifact;
import org.codehaus.plexus.classworlds.ClassWorld;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.classworlds.realm.DuplicateRealmException;
import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
import org.codehaus.plexus.component.discovery.ComponentDiscoverer;
import org.codehaus.plexus.component.discovery.ComponentDiscovererManager;
import org.codehaus.plexus.component.discovery.ComponentDiscoveryEvent;
import org.codehaus.plexus.component.discovery.ComponentDiscoveryListener;
import org.codehaus.plexus.configuration.PlexusConfigurationException;
import org.codehaus.plexus.context.Context;
import java.net.MalformedURLException;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class RealmScanningUtils
{
private static final String DISCOVERY_REALM_ID = "discovery realm";
public static List scanForComponentSetDescriptors( Artifact artifact,
ComponentDiscoverer discoverer,
Context context,
String discoveryContextId )
throws RealmManagementException
{
ClassWorld discoveryWorld = new ClassWorld();
List componentSetDescriptors;
try
{
// Create an entire new ClassWorld, ClassRealm for discovering
// the immediate components of the extension artifact, so we don't pollute the
// container with component descriptors or realms that don't have any meaning beyond discovery.
ClassRealm discoveryRealm;
try
{
discoveryRealm = discoveryWorld.newRealm( DISCOVERY_REALM_ID );
}
catch ( DuplicateRealmException e )
{
throw new RealmManagementException( discoveryContextId, "Unable to create temporary ClassRealm for local-component discovery.", e );
}
try
{
discoveryRealm.addURL( artifact.getFile().toURL() );
}
catch ( MalformedURLException e )
{
throw new RealmManagementException( discoveryContextId, artifact, "Unable to generate URL from artifact file: " + artifact.getFile() + " for local-component discovery.", e );
}
try
{
// Find the extension component descriptors that exist ONLY in the immediate extension
// artifact...this prevents us from adding plexus-archiver components to the mix, for instance,
// when the extension uses that dependency.
componentSetDescriptors = discoverer.findComponents( context, discoveryRealm );
}
catch ( PlexusConfigurationException e )
{
throw new RealmManagementException( discoveryContextId, "Unable to discover components in artifact: " + artifact.getId(), e );
}
}
finally
{
Collection realms = discoveryWorld.getRealms();
for ( Iterator it = realms.iterator(); it.hasNext(); )
{
ClassRealm realm = (ClassRealm) it.next();
try
{
discoveryWorld.disposeRealm( realm.getId() );
}
catch ( NoSuchRealmException e )
{
}
}
}
return componentSetDescriptors;
}
public static ComponentDiscovererManager getDummyComponentDiscovererManager()
{
return new DummyDiscovererManager();
}
private static final class DummyDiscovererManager implements ComponentDiscovererManager
{
public void fireComponentDiscoveryEvent( ComponentDiscoveryEvent arg0 )
{
}
public List getComponentDiscoverers()
{
return null;
}
public Map getComponentDiscoveryListeners()
{
return null;
}
public List getListeners()
{
return null;
}
public void initialize()
{
}
public void registerComponentDiscoveryListener( ComponentDiscoveryListener l )
{
}
public void removeComponentDiscoveryListener( ComponentDiscoveryListener l )
{
}
}
}