From f838337b7a8be8466818346561afb7295ac60d12 Mon Sep 17 00:00:00 2001 From: John Dennis Casey Date: Thu, 31 Jan 2008 23:29:18 +0000 Subject: [PATCH] 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 --- .../errors/ExtensionErrorReporterAspect.aj | 3 +- .../binding/DefaultMojoBindingFactory.java | 13 +- .../maven/plugin/DefaultPluginManager.java | 99 +------ .../plugin/DefaultPluginManagerSupport.java | 262 ++++++++++++++++++ .../maven/plugin/PluginManagerSupport.java | 48 ++++ .../plugin/loader/DefaultPluginLoader.java | 122 -------- .../loader/DefaultPluginPrefixLoader.java | 182 ++++++++++++ .../maven/plugin/loader/PluginLoader.java | 15 - .../plugin/loader/PluginPrefixLoader.java | 25 ++ .../resources/META-INF/plexus/components.xml | 43 ++- .../maven/realm/DefaultMavenRealmManager.java | 163 +++-------- .../maven/realm/RealmScanningUtils.java | 130 +++++++++ 12 files changed, 734 insertions(+), 371 deletions(-) create mode 100644 maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManagerSupport.java create mode 100644 maven-core/src/main/java/org/apache/maven/plugin/PluginManagerSupport.java create mode 100644 maven-core/src/main/java/org/apache/maven/plugin/loader/DefaultPluginPrefixLoader.java create mode 100644 maven-core/src/main/java/org/apache/maven/plugin/loader/PluginPrefixLoader.java create mode 100644 maven-project/src/main/java/org/apache/maven/realm/RealmScanningUtils.java diff --git a/maven-core/src/main/aspect/org/apache/maven/errors/ExtensionErrorReporterAspect.aj b/maven-core/src/main/aspect/org/apache/maven/errors/ExtensionErrorReporterAspect.aj index 9e8dfe05b8..c778d2594c 100644 --- a/maven-core/src/main/aspect/org/apache/maven/errors/ExtensionErrorReporterAspect.aj +++ b/maven-core/src/main/aspect/org/apache/maven/errors/ExtensionErrorReporterAspect.aj @@ -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 ); } diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/binding/DefaultMojoBindingFactory.java b/maven-core/src/main/java/org/apache/maven/lifecycle/binding/DefaultMojoBindingFactory.java index ce7135bb1e..e3c416af96 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/binding/DefaultMojoBindingFactory.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/binding/DefaultMojoBindingFactory.java @@ -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 ) ) { diff --git a/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java b/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java index 5de1ef8173..59ff044c61 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java @@ -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, diff --git a/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManagerSupport.java b/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManagerSupport.java new file mode 100644 index 0000000000..0fc4df2060 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManagerSupport.java @@ -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; + } +} diff --git a/maven-core/src/main/java/org/apache/maven/plugin/PluginManagerSupport.java b/maven-core/src/main/java/org/apache/maven/plugin/PluginManagerSupport.java new file mode 100644 index 0000000000..7389ae724e --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/plugin/PluginManagerSupport.java @@ -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 ); + +} diff --git a/maven-core/src/main/java/org/apache/maven/plugin/loader/DefaultPluginLoader.java b/maven-core/src/main/java/org/apache/maven/plugin/loader/DefaultPluginLoader.java index 77a23d577a..aaa76084c8 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/loader/DefaultPluginLoader.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/loader/DefaultPluginLoader.java @@ -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): - *
- *
    - *
  1. Search for a plugin that has already been loaded with the specified prefix
  2. - *
  3. Search for a plugin configured in the POM that has a matching prefix
  4. - *
  5. Search the pluginGroups specified in the settings.xml for a matching plugin
  6. - *
  7. Use groupId == org.apache.maven.plugins, and artifactId == maven-<prefix>-plugin, - * and try to resolve based on that.
  8. - *
- */ - 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. diff --git a/maven-core/src/main/java/org/apache/maven/plugin/loader/DefaultPluginPrefixLoader.java b/maven-core/src/main/java/org/apache/maven/plugin/loader/DefaultPluginPrefixLoader.java new file mode 100644 index 0000000000..084691d8d0 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/plugin/loader/DefaultPluginPrefixLoader.java @@ -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): + *
+ *
    + *
  1. Search for a plugin that has already been loaded with the specified prefix
  2. + *
  3. Search for a plugin configured in the POM that has a matching prefix
  4. + *
  5. Search the pluginGroups specified in the settings.xml for a matching plugin
  6. + *
  7. Use groupId == org.apache.maven.plugins, and artifactId == maven-<prefix>-plugin, + * and try to resolve based on that.
  8. + *
+ */ + 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; + } + +} diff --git a/maven-core/src/main/java/org/apache/maven/plugin/loader/PluginLoader.java b/maven-core/src/main/java/org/apache/maven/plugin/loader/PluginLoader.java index 1fc47b7e17..e763002c40 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/loader/PluginLoader.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/loader/PluginLoader.java @@ -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): - *
- *
    - *
  1. Search for a plugin that has already been loaded with the specified prefix
  2. - *
  3. Search for a plugin configured in the POM that has a matching prefix
  4. - *
  5. Search the pluginGroups specified in the settings.xml for a matching plugin
  6. - *
  7. Use groupId == org.apache.maven.plugins, and artifactId == maven-<prefix>-plugin, - * and try to resolve based on that.
  8. - *
- */ - PluginDescriptor findPluginForPrefix( String prefix, MavenProject project, MavenSession session ) - throws PluginLoaderException; - } diff --git a/maven-core/src/main/java/org/apache/maven/plugin/loader/PluginPrefixLoader.java b/maven-core/src/main/java/org/apache/maven/plugin/loader/PluginPrefixLoader.java new file mode 100644 index 0000000000..166f0e309a --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/plugin/loader/PluginPrefixLoader.java @@ -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): + *
+ *
    + *
  1. Search for a plugin that has already been loaded with the specified prefix
  2. + *
  3. Search for a plugin configured in the POM that has a matching prefix
  4. + *
  5. Search the pluginGroups specified in the settings.xml for a matching plugin
  6. + *
  7. Use groupId == org.apache.maven.plugins, and artifactId == maven-<prefix>-plugin, + * and try to resolve based on that.
  8. + *
+ */ + Plugin findPluginForPrefix( String prefix, MavenProject project, MavenSession session ) + throws PluginLoaderException; + +} diff --git a/maven-core/src/main/resources/META-INF/plexus/components.xml b/maven-core/src/main/resources/META-INF/plexus/components.xml index 3f7a86b33f..04837a09ea 100644 --- a/maven-core/src/main/resources/META-INF/plexus/components.xml +++ b/maven-core/src/main/resources/META-INF/plexus/components.xml @@ -209,6 +209,9 @@ under the License. org.apache.maven.plugin.PluginManager org.apache.maven.plugin.DefaultPluginManager + + org.apache.maven.plugin.PluginManagerSupport + org.apache.maven.ArtifactFilterManager @@ -690,10 +693,21 @@ under the License. org.apache.maven.plugin.loader.DefaultPluginLoader - org.apache.maven.plugin.MavenPluginCollector + org.apache.maven.plugin.PluginManager + + + + + + org.apache.maven.plugin.loader.PluginPrefixLoader + default + org.apache.maven.plugin.loader.DefaultPluginPrefixLoader + + + org.apache.maven.plugin.PluginManagerSupport - org.apache.maven.plugin.PluginManager + org.apache.maven.plugin.MavenPluginCollector org.apache.maven.plugin.PluginMappingManager @@ -821,7 +835,7 @@ under the License. org.apache.maven.lifecycle.binding.DefaultMojoBindingFactory - org.apache.maven.plugin.loader.PluginLoader + org.apache.maven.plugin.loader.PluginPrefixLoader @@ -850,5 +864,28 @@ under the License. + + + org.apache.maven.plugin.PluginManagerSupport + default + org.apache.maven.plugin.DefaultPluginManagerSupport + + + org.apache.maven.plugin.version.PluginVersionManager + + + org.apache.maven.artifact.resolver.ArtifactResolver + + + org.apache.maven.artifact.factory.ArtifactFactory + + + org.apache.maven.project.MavenProjectBuilder + + + org.apache.maven.execution.RuntimeInformation + + + diff --git a/maven-project/src/main/java/org/apache/maven/realm/DefaultMavenRealmManager.java b/maven-project/src/main/java/org/apache/maven/realm/DefaultMavenRealmManager.java index 8303bcb33f..a0310cb658 100644 --- a/maven-project/src/main/java/org/apache/maven/realm/DefaultMavenRealmManager.java +++ b/maven-project/src/main/java/org/apache/maven/realm/DefaultMavenRealmManager.java @@ -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 ); diff --git a/maven-project/src/main/java/org/apache/maven/realm/RealmScanningUtils.java b/maven-project/src/main/java/org/apache/maven/realm/RealmScanningUtils.java new file mode 100644 index 0000000000..4360c0cb5f --- /dev/null +++ b/maven-project/src/main/java/org/apache/maven/realm/RealmScanningUtils.java @@ -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 ) + { + } + + } +}