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
This commit is contained in:
Benjamin Bentmann 2009-08-20 12:57:39 +00:00
parent 43e0979b5e
commit 2f4b79e4bb
15 changed files with 857 additions and 194 deletions

View File

@ -21,7 +21,6 @@
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.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;

View File

@ -15,10 +15,7 @@
* 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.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.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<Lifecycle> lifecycles;
@ -1229,9 +1226,7 @@ Xpp3Dom convert( MojoDescriptor mojoDescriptor )
return dom;
}
private Map<String,Plugin> pluginPrefixes = new HashMap<String,Plugin>();
//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 @@ Plugin findPluginForPrefix( String prefix, MavenSession session )
{
// [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<String,Plugin> pluginPrefixes )
{
try
{
Metadata pluginGroupMetadata = readMetadata( pluginGroupMetadataFile );
List<org.apache.maven.artifact.repository.metadata.Plugin> 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
/*

View File

@ -32,6 +32,7 @@
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;
/**

View File

@ -20,7 +20,6 @@
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 @@ MojoDescriptor getMojoDescriptor( Plugin plugin, String goal, RepositoryRequest
void executeMojo( MavenSession session, MojoExecution execution )
throws MojoFailureException, MojoExecutionException, PluginConfigurationException, PluginManagerException;
ClassRealm getPluginRealm( MavenSession session, PluginDescriptor pluginDescriptor )
throws PluginManagerException;
}
}

View File

@ -43,6 +43,11 @@
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 Map getPluginComponents( Plugin plugin, String role )
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 )

View File

@ -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<String> 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<String> getPluginGroups()
{
if ( pluginGroups == null )
{
pluginGroups = new ArrayList<String>();
}
return pluginGroups;
}
public DefaultPluginPrefixRequest setPluginGroups( List<String> 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<ArtifactRepository> getRemoteRepositories()
{
return repositoryRequest.getRemoteRepositories();
}
public DefaultPluginPrefixRequest setRemoteRepositories( List<ArtifactRepository> remoteRepositories )
{
repositoryRequest.setRemoteRepositories( remoteRepositories );
return this;
}
public boolean isOffline()
{
return repositoryRequest.isOffline();
}
public DefaultPluginPrefixRequest setOffline( boolean offline )
{
repositoryRequest.setOffline( offline );
return this;
}
}

View File

@ -1,4 +1,4 @@
package org.apache.maven.lifecycle;
package org.apache.maven.plugin.prefix;
/*
* Licensed to the Apache Software Foundation (ASF) under one

View File

@ -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<String> 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<String> 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<ArtifactRepository> getRemoteRepositories();
/**
* Sets the remote repositories to use. <em>Note:</em> 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<ArtifactRepository> 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 );
}

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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<Plugin> 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<org.apache.maven.artifact.repository.metadata.Plugin> 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;
}
}

View File

@ -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;
}
}

View File

@ -102,7 +102,8 @@ public interface PluginVersionRequest
List<ArtifactRepository> getRemoteRepositories();
/**
* Sets the remote repositories to use.
* Sets the remote repositories to use. <em>Note:</em> 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}.

View File

@ -86,7 +86,7 @@ public PluginVersionResult resolve( PluginVersionRequest request )
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 PluginVersionResult resolve( PluginVersionRequest request )
{
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;
}

View File

@ -48,6 +48,9 @@
<requirement>
<role>org.apache.maven.plugin.version.PluginVersionResolver</role>
</requirement>
<requirement>
<role>org.apache.maven.plugin.prefix.PluginPrefixResolver</role>
</requirement>
</requirements>
<configuration>
<lifecycles>