From 2f4b79e4bb9162f0c343a9fa691d9ca7544a7f2f Mon Sep 17 00:00:00 2001 From: Benjamin Bentmann Date: Thu, 20 Aug 2009 12:57:39 +0000 Subject: [PATCH] o Moved plugin prefix resolution into a dedicated component o Completed compat impl of legacy plugin manager git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@806153 13f79535-47bb-0310-9956-ffa450edef68 --- .../exception/DefaultExceptionHandler.java | 2 +- .../lifecycle/DefaultLifecycleExecutor.java | 196 +----------- .../maven/lifecycle/LifecycleExecutor.java | 1 + .../maven/plugin/BuildPluginManager.java | 5 +- .../plugin/internal/DefaultPluginManager.java | 49 ++- .../prefix/DefaultPluginPrefixRequest.java | 167 +++++++++++ .../NoPluginFoundForPrefixException.java | 2 +- .../plugin/prefix/PluginPrefixRequest.java | 146 +++++++++ .../plugin/prefix/PluginPrefixResolver.java | 41 +++ .../plugin/prefix/PluginPrefixResult.java | 54 ++++ .../internal/DefaultPluginPrefixResolver.java | 282 ++++++++++++++++++ .../internal/DefaultPluginPrefixResult.java | 89 ++++++ .../plugin/version/PluginVersionRequest.java | 3 +- .../DefaultPluginVersionResolver.java | 11 +- .../resources/META-INF/plexus/components.xml | 3 + 15 files changed, 857 insertions(+), 194 deletions(-) create mode 100644 maven-core/src/main/java/org/apache/maven/plugin/prefix/DefaultPluginPrefixRequest.java rename maven-core/src/main/java/org/apache/maven/{lifecycle => plugin/prefix}/NoPluginFoundForPrefixException.java (97%) create mode 100644 maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixRequest.java create mode 100644 maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixResolver.java create mode 100644 maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixResult.java create mode 100644 maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResolver.java create mode 100644 maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResult.java diff --git a/maven-core/src/main/java/org/apache/maven/exception/DefaultExceptionHandler.java b/maven-core/src/main/java/org/apache/maven/exception/DefaultExceptionHandler.java index 9d76217706..6438f59a04 100644 --- a/maven-core/src/main/java/org/apache/maven/exception/DefaultExceptionHandler.java +++ b/maven-core/src/main/java/org/apache/maven/exception/DefaultExceptionHandler.java @@ -21,7 +21,6 @@ package org.apache.maven.exception; import org.apache.maven.artifact.resolver.ArtifactNotFoundException; import org.apache.maven.artifact.resolver.ArtifactResolutionException; -import org.apache.maven.lifecycle.NoPluginFoundForPrefixException; import org.apache.maven.plugin.CycleDetectedInPluginGraphException; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; @@ -29,6 +28,7 @@ import org.apache.maven.plugin.MojoNotFoundException; import org.apache.maven.plugin.PluginDescriptorParsingException; import org.apache.maven.plugin.PluginNotFoundException; import org.apache.maven.plugin.PluginResolutionException; +import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.util.StringUtils; diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java b/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java index 8b75dded91..d3a71b4a41 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java @@ -15,10 +15,7 @@ package org.apache.maven.lifecycle; * the License. */ -import java.io.File; -import java.io.FileNotFoundException; import java.io.IOException; -import java.io.Reader; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -31,12 +28,8 @@ import java.util.Set; import java.util.StringTokenizer; import org.apache.maven.ProjectDependenciesResolver; -import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.repository.DefaultRepositoryRequest; import org.apache.maven.artifact.repository.RepositoryRequest; -import org.apache.maven.artifact.repository.metadata.Metadata; -import org.apache.maven.artifact.repository.metadata.RepositoryMetadataReadException; -import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader; import org.apache.maven.execution.BuildFailure; import org.apache.maven.execution.BuildSuccess; import org.apache.maven.execution.MavenExecutionRequest; @@ -63,22 +56,23 @@ import org.apache.maven.plugin.descriptor.Parameter; import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.plugin.lifecycle.Execution; import org.apache.maven.plugin.lifecycle.Phase; +import org.apache.maven.plugin.prefix.DefaultPluginPrefixRequest; +import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException; +import org.apache.maven.plugin.prefix.PluginPrefixRequest; +import org.apache.maven.plugin.prefix.PluginPrefixResolver; +import org.apache.maven.plugin.prefix.PluginPrefixResult; import org.apache.maven.plugin.version.DefaultPluginVersionRequest; import org.apache.maven.plugin.version.PluginVersionRequest; import org.apache.maven.plugin.version.PluginVersionResolutionException; import org.apache.maven.plugin.version.PluginVersionResolver; import org.apache.maven.project.MavenProject; import org.apache.maven.repository.RepositorySystem; -import org.apache.maven.wagon.ResourceDoesNotExistException; -import org.apache.maven.wagon.TransferFailedException; import org.codehaus.plexus.classworlds.realm.ClassRealm; import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.configuration.PlexusConfiguration; import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable; import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException; -import org.codehaus.plexus.util.IOUtil; -import org.codehaus.plexus.util.ReaderFactory; import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.xml.Xpp3Dom; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; @@ -106,6 +100,9 @@ public class DefaultLifecycleExecutor @Requirement private PluginVersionResolver pluginVersionResolver; + + @Requirement + private PluginPrefixResolver pluginPrefixResolver; // @Configuration(source="org/apache/maven/lifecycle/lifecycles.xml") private List lifecycles; @@ -1229,9 +1226,7 @@ public class DefaultLifecycleExecutor return dom; } - - private Map pluginPrefixes = new HashMap(); - + //TODO: take repo mans into account as one may be aggregating prefixes of many //TODO: collect at the root of the repository, read the one at the root, and fetch remote if something is missing // or the user forces the issue @@ -1240,177 +1235,16 @@ public class DefaultLifecycleExecutor { // [prefix]:[goal] - Plugin plugin = pluginPrefixes.get( prefix ); + PluginPrefixRequest prefixRequest = new DefaultPluginPrefixRequest( session ).setPrefix( prefix ); + PluginPrefixResult prefixResult = pluginPrefixResolver.resolve( prefixRequest ); - if ( plugin != null ) - { - return plugin; - } + Plugin plugin = new Plugin(); + plugin.setGroupId( prefixResult.getGroupId() ); + plugin.setArtifactId( prefixResult.getArtifactId() ); - MavenProject project = session.getCurrentProject(); - - if ( project != null ) - { - RepositoryRequest repositoryRequest = getRepositoryRequest( session, project ); - - for ( Plugin buildPlugin : project.getBuildPlugins() ) - { - try - { - PluginDescriptor pluginDescriptor = pluginManager.loadPlugin( buildPlugin, repositoryRequest ); - - if ( prefix.equals( pluginDescriptor.getGoalPrefix() ) ) - { - Plugin p = new Plugin(); - p.setGroupId( buildPlugin.getGroupId() ); - p.setArtifactId( buildPlugin.getArtifactId() ); - pluginPrefixes.put( prefix, p ); - return p; - } - } - catch ( Exception e ) - { - logger.debug( "Failed to retrieve plugin descriptor for " + buildPlugin, e ); - } - } - } - - // Process all plugin groups in the local repository first to see if we get a hit. A developer may have been - // developing a plugin locally and installing. - // - for ( String pluginGroup : session.getPluginGroups() ) - { - String localPath = pluginGroup.replace( '.', '/' ) + "/" + "maven-metadata-" + session.getLocalRepository().getId() + ".xml"; - - File destination = new File( session.getLocalRepository().getBasedir(), localPath ); - - if ( destination.exists() ) - { - processPluginGroupMetadata( pluginGroup, destination, pluginPrefixes ); - - plugin = pluginPrefixes.get( prefix ); - - if ( plugin != null ) - { - return plugin; - } - } - } - - // Process all the remote repositories. - // - for ( String pluginGroup : session.getPluginGroups() ) - { - for ( ArtifactRepository repository : session.getCurrentProject().getPluginArtifactRepositories() ) - { - try - { - String localPath = pluginGroup.replace( '.', '/' ) + "/" + "maven-metadata-" + repository.getId() + ".xml"; - - File destination = new File( session.getLocalRepository().getBasedir(), localPath ); - - String remotePath = pluginGroup.replace( '.', '/' ) + "/" + "maven-metadata.xml"; - - repositorySystem.retrieve( repository, destination, remotePath, session.getRequest().getTransferListener() ); - - processPluginGroupMetadata( pluginGroup, destination, pluginPrefixes ); - - plugin = pluginPrefixes.get( prefix ); - - if ( plugin != null ) - { - return plugin; - } - } - catch ( TransferFailedException e ) - { - continue; - } - catch ( ResourceDoesNotExistException e ) - { - continue; - } - } - - } - - throw new NoPluginFoundForPrefixException( prefix, session.getLocalRepository(), session.getCurrentProject().getPluginArtifactRepositories() ); + return plugin; } - - // Keep track of the repository that provided the prefix mapping - // - private class PluginPrefix - { - private Plugin plugin; - - private ArtifactRepository repository; - public PluginPrefix( Plugin plugin, ArtifactRepository repository ) - { - this.plugin = plugin; - this.repository = repository; - } - } - - - private void processPluginGroupMetadata( String pluginGroup, File pluginGroupMetadataFile, Map pluginPrefixes ) - { - try - { - Metadata pluginGroupMetadata = readMetadata( pluginGroupMetadataFile ); - - List plugins = pluginGroupMetadata.getPlugins(); - - if ( plugins != null ) - { - for ( org.apache.maven.artifact.repository.metadata.Plugin metadataPlugin : plugins ) - { - Plugin p = new Plugin(); - p.setGroupId( pluginGroup ); - p.setArtifactId( metadataPlugin.getArtifactId() ); - pluginPrefixes.put( metadataPlugin.getPrefix(), p ); - } - } - } - catch ( RepositoryMetadataReadException e ) - { - logger.warn( "Error reading plugin group metadata: ", e ); - } - } - - protected Metadata readMetadata( File mappingFile ) - throws RepositoryMetadataReadException - { - Metadata result; - - Reader reader = null; - try - { - reader = ReaderFactory.newXmlReader( mappingFile ); - - MetadataXpp3Reader mappingReader = new MetadataXpp3Reader(); - - result = mappingReader.read( reader, false ); - } - catch ( FileNotFoundException e ) - { - throw new RepositoryMetadataReadException( "Cannot read metadata from '" + mappingFile + "'", e ); - } - catch ( IOException e ) - { - throw new RepositoryMetadataReadException( "Cannot read metadata from '" + mappingFile + "': " + e.getMessage(), e ); - } - catch ( XmlPullParserException e ) - { - throw new RepositoryMetadataReadException( "Cannot read metadata from '" + mappingFile + "': " + e.getMessage(), e ); - } - finally - { - IOUtil.close( reader ); - } - return result; - } - // These are checks that should be available in real time to IDEs /* diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java b/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java index 1dd1f2993b..dba19f7193 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java @@ -32,6 +32,7 @@ import org.apache.maven.plugin.PluginDescriptorParsingException; import org.apache.maven.plugin.PluginManagerException; import org.apache.maven.plugin.PluginNotFoundException; import org.apache.maven.plugin.PluginResolutionException; +import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException; import org.apache.maven.plugin.version.PluginVersionResolutionException; /** diff --git a/maven-core/src/main/java/org/apache/maven/plugin/BuildPluginManager.java b/maven-core/src/main/java/org/apache/maven/plugin/BuildPluginManager.java index 5f1b833df7..15c7592349 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/BuildPluginManager.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/BuildPluginManager.java @@ -20,7 +20,6 @@ import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Plugin; import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor; -import org.codehaus.plexus.classworlds.realm.ClassRealm; /** * @author Jason van Zyl @@ -38,6 +37,4 @@ public interface BuildPluginManager void executeMojo( MavenSession session, MojoExecution execution ) throws MojoFailureException, MojoExecutionException, PluginConfigurationException, PluginManagerException; - ClassRealm getPluginRealm( MavenSession session, PluginDescriptor pluginDescriptor ) - throws PluginManagerException; -} \ No newline at end of file +} diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginManager.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginManager.java index 7234c9ac74..5c1c01b062 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginManager.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginManager.java @@ -43,6 +43,11 @@ import org.apache.maven.plugin.PluginManagerException; import org.apache.maven.plugin.PluginNotFoundException; import org.apache.maven.plugin.PluginResolutionException; import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.apache.maven.plugin.prefix.DefaultPluginPrefixRequest; +import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException; +import org.apache.maven.plugin.prefix.PluginPrefixRequest; +import org.apache.maven.plugin.prefix.PluginPrefixResolver; +import org.apache.maven.plugin.prefix.PluginPrefixResult; import org.apache.maven.plugin.version.DefaultPluginVersionRequest; import org.apache.maven.plugin.version.PluginVersionNotFoundException; import org.apache.maven.plugin.version.PluginVersionRequest; @@ -74,6 +79,9 @@ public class DefaultPluginManager @Requirement private PluginVersionResolver pluginVersionResolver; + @Requirement + private PluginPrefixResolver pluginPrefixResolver; + @Requirement private LegacySupport legacySupport; @@ -165,14 +173,47 @@ public class DefaultPluginManager public Plugin getPluginDefinitionForPrefix( String prefix, MavenSession session, MavenProject project ) { - // TODO Auto-generated method stub - return null; + PluginPrefixRequest request = new DefaultPluginPrefixRequest( session ); + request.setPrefix( prefix ); + request.setPom( project.getModel() ); + + try + { + PluginPrefixResult result = pluginPrefixResolver.resolve( request ); + + Plugin plugin = new Plugin(); + plugin.setGroupId( result.getGroupId() ); + plugin.setArtifactId( result.getArtifactId() ); + + return plugin; + } + catch ( NoPluginFoundForPrefixException e ) + { + return null; + } } public PluginDescriptor getPluginDescriptorForPrefix( String prefix ) { - // TODO Auto-generated method stub - return null; + MavenSession session = legacySupport.getSession(); + + PluginPrefixRequest request = new DefaultPluginPrefixRequest( session ); + request.setPrefix( prefix ); + + try + { + PluginPrefixResult result = pluginPrefixResolver.resolve( request ); + + Plugin plugin = new Plugin(); + plugin.setGroupId( result.getGroupId() ); + plugin.setArtifactId( result.getArtifactId() ); + + return loadPluginDescriptor( plugin, session.getCurrentProject(), session ); + } + catch ( Exception e ) + { + return null; + } } public PluginDescriptor loadPluginDescriptor( Plugin plugin, MavenProject project, MavenSession session ) diff --git a/maven-core/src/main/java/org/apache/maven/plugin/prefix/DefaultPluginPrefixRequest.java b/maven-core/src/main/java/org/apache/maven/plugin/prefix/DefaultPluginPrefixRequest.java new file mode 100644 index 0000000000..f397301ebc --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/plugin/prefix/DefaultPluginPrefixRequest.java @@ -0,0 +1,167 @@ +package org.apache.maven.plugin.prefix; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayList; +import java.util.List; + +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.repository.DefaultRepositoryRequest; +import org.apache.maven.artifact.repository.RepositoryCache; +import org.apache.maven.artifact.repository.RepositoryRequest; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.Model; +import org.apache.maven.project.MavenProject; + +/** + * Collects settings required to resolve a plugin prefix. + * + * @author Benjamin Bentmann + */ +public class DefaultPluginPrefixRequest + implements PluginPrefixRequest +{ + + private String prefix; + + private List pluginGroups; + + private Model pom; + + private RepositoryRequest repositoryRequest; + + public DefaultPluginPrefixRequest() + { + repositoryRequest = new DefaultRepositoryRequest(); + } + + public DefaultPluginPrefixRequest( RepositoryRequest repositoryRequest ) + { + this.repositoryRequest = new DefaultRepositoryRequest( repositoryRequest ); + } + + public DefaultPluginPrefixRequest( MavenSession session ) + { + this.repositoryRequest = new DefaultRepositoryRequest(); + + setCache( session.getRepositoryCache() ); + setLocalRepository( session.getLocalRepository() ); + setOffline( session.isOffline() ); + + MavenProject project = session.getCurrentProject(); + if ( project != null ) + { + setRemoteRepositories( project.getPluginArtifactRepositories() ); + setPom( project.getModel() ); + } + + setPluginGroups( session.getPluginGroups() ); + } + + public String getPrefix() + { + return prefix; + } + + public DefaultPluginPrefixRequest setPrefix( String prefix ) + { + this.prefix = prefix; + + return this; + } + + public List getPluginGroups() + { + if ( pluginGroups == null ) + { + pluginGroups = new ArrayList(); + } + + return pluginGroups; + } + + public DefaultPluginPrefixRequest setPluginGroups( List pluginGroups ) + { + this.pluginGroups = pluginGroups; + + return this; + } + + public Model getPom() + { + return pom; + } + + public DefaultPluginPrefixRequest setPom( Model pom ) + { + this.pom = pom; + + return this; + } + + public RepositoryCache getCache() + { + return repositoryRequest.getCache(); + } + + public DefaultPluginPrefixRequest setCache( RepositoryCache cache ) + { + repositoryRequest.setCache( cache ); + + return this; + } + + public ArtifactRepository getLocalRepository() + { + return repositoryRequest.getLocalRepository(); + } + + public DefaultPluginPrefixRequest setLocalRepository( ArtifactRepository localRepository ) + { + repositoryRequest.setLocalRepository( localRepository ); + + return this; + } + + public List getRemoteRepositories() + { + return repositoryRequest.getRemoteRepositories(); + } + + public DefaultPluginPrefixRequest setRemoteRepositories( List remoteRepositories ) + { + repositoryRequest.setRemoteRepositories( remoteRepositories ); + + return this; + } + + public boolean isOffline() + { + return repositoryRequest.isOffline(); + } + + public DefaultPluginPrefixRequest setOffline( boolean offline ) + { + repositoryRequest.setOffline( offline ); + + return this; + } + +} diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/NoPluginFoundForPrefixException.java b/maven-core/src/main/java/org/apache/maven/plugin/prefix/NoPluginFoundForPrefixException.java similarity index 97% rename from maven-core/src/main/java/org/apache/maven/lifecycle/NoPluginFoundForPrefixException.java rename to maven-core/src/main/java/org/apache/maven/plugin/prefix/NoPluginFoundForPrefixException.java index 4219256d2b..fa96a17883 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/NoPluginFoundForPrefixException.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/prefix/NoPluginFoundForPrefixException.java @@ -1,4 +1,4 @@ -package org.apache.maven.lifecycle; +package org.apache.maven.plugin.prefix; /* * Licensed to the Apache Software Foundation (ASF) under one diff --git a/maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixRequest.java b/maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixRequest.java new file mode 100644 index 0000000000..893eaf2043 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixRequest.java @@ -0,0 +1,146 @@ +package org.apache.maven.plugin.prefix; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.List; + +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.repository.RepositoryCache; +import org.apache.maven.artifact.repository.RepositoryRequest; +import org.apache.maven.model.Model; + +/** + * Collects settings required to resolve a plugin prefix. + * + * @author Benjamin Bentmann + */ +public interface PluginPrefixRequest + extends RepositoryRequest +{ + + /** + * Gets the prefix of the plugin. + * + * @return The prefix of the plugin. + */ + String getPrefix(); + + /** + * Sets the prefix of the plugin. + * + * @param prefix The prefix of the plugin. + * @return This request, never {@code null}. + */ + PluginPrefixRequest setPrefix( String prefix ); + + /** + * Gets the list of group ids to scan for the plugin prefix. + * + * @return The list of group ids to scan for the plugin prefix, never {@code null}. + */ + List getPluginGroups(); + + /** + * Sets the list of group ids to scan for the plugin prefix. + * + * @param pluginGroups The list of group ids to scan for the plugin prefix, may be {@code null}. + * @return This request, never {@code null}. + */ + PluginPrefixRequest setPluginGroups( List pluginGroups ); + + /** + * Gets the POM whose build plugins are to be scanned for the prefix. + * + * @return The POM whose build plugins are to be scanned for the prefix or {@code null} to only search the plugin + * repositories. + */ + Model getPom(); + + /** + * Sets the POM whose build plugins are to be scanned for the prefix. + * + * @param pom The POM whose build plugins are to be scanned for the prefix, may be {@code null} to only search the + * plugin repositories. + * @return This request, never {@code null}. + */ + PluginPrefixRequest setPom( Model pom ); + + /** + * Indicates whether network access to remote repositories has been disabled. + * + * @return {@code true} if remote access has been disabled, {@code false} otherwise. + */ + boolean isOffline(); + + /** + * Enables/disables network access to remote repositories. + * + * @param offline {@code true} to disable remote access, {@code false} to allow network access. + * @return This request, never {@code null}. + */ + PluginPrefixRequest setOffline( boolean offline ); + + /** + * Gets the local repository to use. + * + * @return The local repository to use or {@code null} if not set. + */ + ArtifactRepository getLocalRepository(); + + /** + * Sets the local repository to use. + * + * @param localRepository The local repository to use. + * @return This request, never {@code null}. + */ + PluginPrefixRequest setLocalRepository( ArtifactRepository localRepository ); + + /** + * Gets the remote repositories to use. + * + * @return The remote repositories to use, never {@code null}. + */ + List getRemoteRepositories(); + + /** + * Sets the remote repositories to use. Note: When creating a request from a project, be sure to use the + * plugin artifact repositories and not the regular artifact repositories. + * + * @param remoteRepositories The remote repositories to use. + * @return This request, never {@code null}. + */ + PluginPrefixRequest setRemoteRepositories( List remoteRepositories ); + + /** + * Gets the repository cache to use. + * + * @return The repository cache to use or {@code null} if none. + */ + RepositoryCache getCache(); + + /** + * Sets the repository cache to use. + * + * @param cache The repository cache to use, may be {@code null}. + * @return This request, never {@code null}. + */ + PluginPrefixRequest setCache( RepositoryCache cache ); + +} diff --git a/maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixResolver.java b/maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixResolver.java new file mode 100644 index 0000000000..05d9b0f73f --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixResolver.java @@ -0,0 +1,41 @@ +package org.apache.maven.plugin.prefix; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Resolves a plugin prefix. + * + * @author Benjamin Bentmann + */ +public interface PluginPrefixResolver +{ + + /** + * Resolves the plugin prefix for the specified request. + * + * @param request The request that holds the details about the plugin and the repositories to consult, must not be + * {@code null}. + * @return The result of the prefix resolution, never {@code null}. + * @throws NoPluginFoundForPrefixException If the plugin prefix could not be resolved. + */ + PluginPrefixResult resolve( PluginPrefixRequest request ) + throws NoPluginFoundForPrefixException; + +} diff --git a/maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixResult.java b/maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixResult.java new file mode 100644 index 0000000000..e754a341a6 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixResult.java @@ -0,0 +1,54 @@ +package org.apache.maven.plugin.prefix; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.maven.artifact.repository.ArtifactRepository; + +/** + * Describes the result of a plugin prefix resolution request. + * + * @author Benjamin Bentmann + */ +public interface PluginPrefixResult +{ + + /** + * The resolved group id for the plugin. + * + * @return The resolved group id for the plugin, never {@code null}. + */ + String getGroupId(); + + /** + * The resolved artifact id for the plugin. + * + * @return The resolved artifact id for the plugin, never {@code null}. + */ + String getArtifactId(); + + /** + * The repository from which the plugin prefix was resolved. + * + * @return The repository from which the plugin prefix was resolved or {@code null} if the prefix was resolved from + * the supplied POM. + */ + ArtifactRepository getRepository(); + +} diff --git a/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResolver.java b/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResolver.java new file mode 100644 index 0000000000..a3edcd2b95 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResolver.java @@ -0,0 +1,282 @@ +package org.apache.maven.plugin.prefix.internal; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.Reader; +import java.util.List; + +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.repository.metadata.Metadata; +import org.apache.maven.artifact.repository.metadata.RepositoryMetadataReadException; +import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader; +import org.apache.maven.model.Build; +import org.apache.maven.model.Plugin; +import org.apache.maven.plugin.BuildPluginManager; +import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException; +import org.apache.maven.plugin.prefix.PluginPrefixRequest; +import org.apache.maven.plugin.prefix.PluginPrefixResolver; +import org.apache.maven.plugin.prefix.PluginPrefixResult; +import org.apache.maven.repository.RepositorySystem; +import org.apache.maven.wagon.ResourceDoesNotExistException; +import org.apache.maven.wagon.TransferFailedException; +import org.codehaus.plexus.component.annotations.Component; +import org.codehaus.plexus.component.annotations.Requirement; +import org.codehaus.plexus.logging.Logger; +import org.codehaus.plexus.util.IOUtil; +import org.codehaus.plexus.util.ReaderFactory; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; + +/** + * Resolves a plugin prefix. + * + * @author Benjamin Bentmann + */ +@Component( role = PluginPrefixResolver.class ) +public class DefaultPluginPrefixResolver + implements PluginPrefixResolver +{ + + @Requirement + private Logger logger; + + @Requirement + private BuildPluginManager pluginManager; + + @Requirement + private RepositorySystem repositorySystem; + + public PluginPrefixResult resolve( PluginPrefixRequest request ) + throws NoPluginFoundForPrefixException + { + PluginPrefixResult result = resolveFromProject( request ); + + if ( result == null ) + { + result = resolveFromRepository( request ); + + if ( result == null ) + { + throw new NoPluginFoundForPrefixException( request.getPrefix(), request.getLocalRepository(), + request.getRemoteRepositories() ); + } + } + + return result; + } + + private PluginPrefixResult resolveFromProject( PluginPrefixRequest request ) + { + PluginPrefixResult result = null; + + if ( request.getPom() != null && request.getPom().getBuild() != null ) + { + Build build = request.getPom().getBuild(); + + result = resolveFromProject( request, build.getPlugins() ); + + if ( result == null && build.getPluginManagement() != null ) + { + result = resolveFromProject( request, build.getPluginManagement().getPlugins() ); + } + } + + return result; + } + + private PluginPrefixResult resolveFromProject( PluginPrefixRequest request, List plugins ) + { + for ( Plugin plugin : plugins ) + { + try + { + PluginDescriptor pluginDescriptor = pluginManager.loadPlugin( plugin, request ); + + if ( request.getPrefix().equals( pluginDescriptor.getGoalPrefix() ) ) + { + return new DefaultPluginPrefixResult( plugin ); + } + } + catch ( Exception e ) + { + if ( logger.isDebugEnabled() ) + { + logger.warn( "Failed to retrieve plugin descriptor for " + plugin + ": " + e.getMessage(), e ); + } + else + { + logger.warn( "Failed to retrieve plugin descriptor for " + plugin + ": " + e.getMessage() ); + } + } + } + + return null; + } + + private PluginPrefixResult resolveFromRepository( PluginPrefixRequest request ) + { + ArtifactRepository localRepository = request.getLocalRepository(); + + // Process all plugin groups in the local repository first to see if we get a hit. A developer may have been + // developing a plugin locally and installing. + // + for ( String pluginGroup : request.getPluginGroups() ) + { + String localPath = + pluginGroup.replace( '.', '/' ) + "/" + "maven-metadata-" + localRepository.getId() + ".xml"; + + File destination = new File( localRepository.getBasedir(), localPath ); + + PluginPrefixResult result = resolveFromRepository( request, pluginGroup, destination, localRepository ); + + if ( result != null ) + { + return result; + } + } + + // Process all the remote repositories. + // + for ( String pluginGroup : request.getPluginGroups() ) + { + for ( ArtifactRepository repository : request.getRemoteRepositories() ) + { + String localPath = + pluginGroup.replace( '.', '/' ) + "/" + "maven-metadata-" + repository.getId() + ".xml"; + + File destination = new File( localRepository.getBasedir(), localPath ); + + if ( !request.isOffline() ) + { + String remotePath = pluginGroup.replace( '.', '/' ) + "/" + "maven-metadata.xml"; + + try + { + repositorySystem.retrieve( repository, destination, remotePath, null ); + } + catch ( TransferFailedException e ) + { + if ( logger.isDebugEnabled() ) + { + logger.warn( "Failed to retrieve " + remotePath + ": " + e.getMessage(), e ); + } + else + { + logger.warn( "Failed to retrieve " + remotePath + ": " + e.getMessage() ); + } + + continue; + } + catch ( ResourceDoesNotExistException e ) + { + continue; + } + } + + PluginPrefixResult result = resolveFromRepository( request, pluginGroup, destination, repository ); + + if ( result != null ) + { + return result; + } + } + } + + return null; + } + + private PluginPrefixResult resolveFromRepository( PluginPrefixRequest request, String pluginGroup, + File metadataFile, ArtifactRepository repository ) + { + if ( metadataFile.isFile() ) + { + try + { + Metadata pluginGroupMetadata = readMetadata( metadataFile ); + + List plugins = pluginGroupMetadata.getPlugins(); + + if ( plugins != null ) + { + for ( org.apache.maven.artifact.repository.metadata.Plugin plugin : plugins ) + { + if ( request.getPrefix().equals( plugin.getPrefix() ) ) + { + return new DefaultPluginPrefixResult( pluginGroup, plugin.getArtifactId(), repository ); + } + } + } + } + catch ( RepositoryMetadataReadException e ) + { + if ( logger.isDebugEnabled() ) + { + logger.warn( "Error reading plugin group metadata: " + e.getMessage(), e ); + } + else + { + logger.warn( "Error reading plugin group metadata: " + e.getMessage() ); + } + } + } + + return null; + } + + private Metadata readMetadata( File mappingFile ) + throws RepositoryMetadataReadException + { + Metadata result; + + Reader reader = null; + try + { + reader = ReaderFactory.newXmlReader( mappingFile ); + + MetadataXpp3Reader mappingReader = new MetadataXpp3Reader(); + + result = mappingReader.read( reader, false ); + } + catch ( FileNotFoundException e ) + { + throw new RepositoryMetadataReadException( "Cannot read metadata from '" + mappingFile + "'", e ); + } + catch ( IOException e ) + { + throw new RepositoryMetadataReadException( "Cannot read metadata from '" + mappingFile + "': " + + e.getMessage(), e ); + } + catch ( XmlPullParserException e ) + { + throw new RepositoryMetadataReadException( "Cannot read metadata from '" + mappingFile + "': " + + e.getMessage(), e ); + } + finally + { + IOUtil.close( reader ); + } + + return result; + } + +} diff --git a/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResult.java b/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResult.java new file mode 100644 index 0000000000..f1e95c4f93 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResult.java @@ -0,0 +1,89 @@ +package org.apache.maven.plugin.prefix.internal; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.model.Plugin; +import org.apache.maven.plugin.prefix.PluginPrefixResult; + +/** + * Describes the result of a plugin prefix resolution request. + * + * @author Benjamin Bentmann + */ +class DefaultPluginPrefixResult + implements PluginPrefixResult +{ + + private String groupId; + + private String artifactId; + + private ArtifactRepository repository; + + public DefaultPluginPrefixResult() + { + // does nothing + } + + public DefaultPluginPrefixResult( Plugin plugin ) + { + groupId = plugin.getGroupId(); + artifactId = plugin.getArtifactId(); + } + + public DefaultPluginPrefixResult( String groupId, String artifactId, ArtifactRepository repository ) + { + this.groupId = groupId; + this.artifactId = artifactId; + this.repository = repository; + } + + public String getGroupId() + { + return groupId; + } + + public void setGroupId( String groupId ) + { + this.groupId = groupId; + } + + public String getArtifactId() + { + return artifactId; + } + + public void setArtifactId( String artifactId ) + { + this.artifactId = artifactId; + } + + public ArtifactRepository getRepository() + { + return repository; + } + + public void setRepository( ArtifactRepository repository ) + { + this.repository = repository; + } + +} diff --git a/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionRequest.java b/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionRequest.java index 215f3a9580..187d473824 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionRequest.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionRequest.java @@ -102,7 +102,8 @@ public interface PluginVersionRequest List getRemoteRepositories(); /** - * Sets the remote repositories to use. + * Sets the remote repositories to use. Note: When creating a request from a project, be sure to use the + * plugin artifact repositories and not the regular artifact repositories. * * @param remoteRepositories The remote repositories to use. * @return This request, never {@code null}. diff --git a/maven-core/src/main/java/org/apache/maven/plugin/version/internal/DefaultPluginVersionResolver.java b/maven-core/src/main/java/org/apache/maven/plugin/version/internal/DefaultPluginVersionResolver.java index 57b6b44881..28bdc6383a 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/version/internal/DefaultPluginVersionResolver.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/version/internal/DefaultPluginVersionResolver.java @@ -86,7 +86,7 @@ public class DefaultPluginVersionResolver artifactMetadataFile = new File( localRepository.getBasedir(), localPath ); - if ( !artifactMetadataFile.exists() /* || user requests snapshot updates */) + if ( !request.isOffline() && !artifactMetadataFile.exists() /* || user requests snapshot updates */) { String remotePath = request.getGroupId().replace( '.', '/' ) + "/" + request.getArtifactId() + "/maven-metadata.xml"; @@ -99,7 +99,14 @@ public class DefaultPluginVersionResolver { error = e; - logger.debug( "Failed to retrieve " + remotePath, e ); + if ( logger.isDebugEnabled() ) + { + logger.warn( "Failed to retrieve " + remotePath + ": " + e.getMessage(), e ); + } + else + { + logger.warn( "Failed to retrieve " + remotePath + ": " + e.getMessage() ); + } continue; } 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 037120ff60..9d400b7ae7 100644 --- a/maven-core/src/main/resources/META-INF/plexus/components.xml +++ b/maven-core/src/main/resources/META-INF/plexus/components.xml @@ -48,6 +48,9 @@ org.apache.maven.plugin.version.PluginVersionResolver + + org.apache.maven.plugin.prefix.PluginPrefixResolver +