Working on: MNG-377

o Added maven-plugin-mapping project to handle repository metadata that contains prefix-to-artifactId mappings for groups of plugins

o Added builder classes for plugin mappings

o Modified maven-artifact and maven-artifact-manager to handle the concept of repository metadata in addition to artifact metadata.

o Added pluginGroups section to settings.xml, new code to merge these lists of plugin groups, and a unit test to ensure that this merge is taking place properly.

o Added maven-plugin-mapping to dependencies of maven-core, along with the list of builds to be performed by mboot.

Should be ready to incorporate plugin mapping consultation into the lifecycle executor and the deploy mojo...



git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@209550 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
John Dennis Casey 2005-07-07 00:17:37 +00:00
parent 2a403e4df3
commit ca59227be1
25 changed files with 622 additions and 4 deletions

View File

@ -20,6 +20,7 @@ import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.DefaultArtifactRepository;
import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
import org.apache.maven.wagon.ConnectionException;
import org.apache.maven.wagon.ResourceDoesNotExistException;
import org.apache.maven.wagon.TransferFailedException;
@ -98,6 +99,14 @@ public class DefaultWagonManager
putRemoteFile( repository, source, repository.pathOfMetadata( artifactMetadata ), null );
}
public void putRepositoryMetadata( File source, RepositoryMetadata metadata, ArtifactRepository repository )
throws TransferFailedException
{
getLogger().info( "Uploading " + metadata );
putRemoteFile( repository, source, metadata.getRepositoryPath(), null );
}
private void putRemoteFile( ArtifactRepository repository, File source, String remotePath,
TransferListener downloadMonitor )
throws TransferFailedException
@ -242,6 +251,16 @@ public class DefaultWagonManager
getRemoteFile( remoteRepository, destination, remotePath, null );
}
public void getRepositoryMetadata( RepositoryMetadata metadata, ArtifactRepository remoteRepository, File destination )
throws TransferFailedException, ResourceDoesNotExistException
{
String remotePath = metadata.getRepositoryPath();
getLogger().info( "Retrieving " + metadata );
getRemoteFile( remoteRepository, destination, remotePath, null );
}
private void getRemoteFile( ArtifactRepository repository, File destination, String remotePath,
TransferListener downloadMonitor )
throws TransferFailedException, ResourceDoesNotExistException, ChecksumFailedException

View File

@ -20,6 +20,7 @@ import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
import org.apache.maven.wagon.ResourceDoesNotExistException;
import org.apache.maven.wagon.TransferFailedException;
import org.apache.maven.wagon.UnsupportedProtocolException;
@ -57,10 +58,17 @@ public interface WagonManager
public void getArtifactMetadata( ArtifactMetadata metadata, ArtifactRepository remoteRepository, File destination )
throws TransferFailedException, ResourceDoesNotExistException;
public void putRepositoryMetadata( File source, RepositoryMetadata metadata, ArtifactRepository repository )
throws TransferFailedException;
public void getRepositoryMetadata( RepositoryMetadata metadata, ArtifactRepository remoteRepository,
File destination )
throws TransferFailedException, ResourceDoesNotExistException;
void addProxy( String protocol, String host, int port, String username, String password, String nonProxyHosts );
void addAuthenticationInfo( String repositoryId, String username, String password, String privateKey,
String passphrase );
String passphrase );
void addMirror( String id, String mirrorOf, String url );

View File

@ -63,6 +63,11 @@ public class DefaultArtifactRepository
{
return layout.pathOfMetadata( artifactMetadata );
}
public String formatDirectory( String directory )
{
return layout.formatDirectory( directory );
}
public String getSnapshotPolicy()
{

View File

@ -0,0 +1,67 @@
package org.apache.maven.artifact.repository.metadata;
import org.apache.maven.artifact.manager.WagonManager;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.wagon.ResourceDoesNotExistException;
import org.apache.maven.wagon.TransferFailedException;
import java.io.File;
public class DefaultRepositoryMetadataManager
implements RepositoryMetadataManager
{
// component requirement
private WagonManager wagonManager;
public void get( RepositoryMetadata metadata, ArtifactRepository remote, ArtifactRepository local )
throws RepositoryMetadataManagementException
{
String realignedPath = local.formatDirectory( metadata.getRepositoryPath() );
realignedPath = realignedPath.replace( File.separatorChar, '/' );
if ( !realignedPath.startsWith( "/" ) )
{
realignedPath = "/" + realignedPath;
}
realignedPath = "/REPOSITORY-INF/" + remote.getId() + realignedPath;
File metadataFile = new File( local.getBasedir(), realignedPath );
try
{
wagonManager.getRepositoryMetadata( metadata, remote, metadataFile );
metadata.setFile( metadataFile );
}
catch ( TransferFailedException e )
{
throw new RepositoryMetadataManagementException( metadata, "Failed to download repository metadata.", e );
}
catch ( ResourceDoesNotExistException e )
{
throw new RepositoryMetadataManagementException( metadata, "Remote repository metadata not found.", e );
}
}
public void put( RepositoryMetadata metadata, ArtifactRepository remote )
throws RepositoryMetadataManagementException
{
File metadataFile = metadata.getFile();
try
{
wagonManager.putRepositoryMetadata( metadataFile, metadata, remote );
metadata.setFile( metadataFile );
}
catch ( TransferFailedException e )
{
throw new RepositoryMetadataManagementException( metadata, "Failed to upload repository metadata.", e );
}
}
}

View File

@ -46,6 +46,8 @@ public interface ArtifactRepository
String pathOf( Artifact artifact );
String pathOfMetadata( ArtifactMetadata artifactMetadata );
String formatDirectory( String directory );
String getUrl();

View File

@ -30,4 +30,6 @@ public interface ArtifactRepositoryLayout
String pathOf( Artifact artifact );
String pathOfMetadata( ArtifactMetadata metadata );
String formatDirectory( String directory );
}

View File

@ -33,7 +33,7 @@ public class DefaultRepositoryLayout
StringBuffer path = new StringBuffer();
path.append( artifact.getGroupId().replace( '.', '/' ) ).append( '/' );
path.append( formatDirectory( artifact.getGroupId() ) ).append( '/' );
path.append( artifact.getArtifactId() ).append( '/' );
path.append( artifact.getBaseVersion() ).append( '/' );
path.append( artifact.getArtifactId() ).append( '-' ).append( artifact.getVersion() );
@ -55,7 +55,7 @@ public class DefaultRepositoryLayout
{
StringBuffer path = new StringBuffer();
path.append( metadata.getGroupId().replace( '.', '/' ) ).append( '/' );
path.append( formatDirectory( metadata.getGroupId() ) ).append( '/' );
path.append( metadata.getArtifactId() ).append( '/' );
if ( !metadata.getBaseVersion().equals( "RELEASE" ) )
{
@ -67,4 +67,8 @@ public class DefaultRepositoryLayout
return path.toString();
}
public String formatDirectory( String directory )
{
return directory.replace( '.', '/' );
}
}

View File

@ -58,5 +58,10 @@ public class LegacyRepositoryLayout
return path.toString();
}
public String formatDirectory( String directory )
{
return directory;
}
}

View File

@ -0,0 +1,14 @@
package org.apache.maven.artifact.repository.metadata;
import java.io.File;
public interface RepositoryMetadata
{
String getRepositoryPath();
void setFile( File metadataFile );
File getFile();
}

View File

@ -0,0 +1,35 @@
package org.apache.maven.artifact.repository.metadata;
public class RepositoryMetadataManagementException
extends Exception
{
private final RepositoryMetadata metadata;
public RepositoryMetadataManagementException( RepositoryMetadata metadata )
{
super( "Failed to resolve repository metadata: " + metadata + ".");
this.metadata = metadata;
}
public RepositoryMetadataManagementException( RepositoryMetadata metadata, String message, Throwable cause )
{
super( "Failed to resolve repository metadata: " + metadata + ". Error was: " + cause.getMessage(), cause );
this.metadata = metadata;
}
public RepositoryMetadataManagementException( RepositoryMetadata metadata, String message )
{
super( "Failed to resolve repository metadata: " + metadata + ".");
this.metadata = metadata;
}
public RepositoryMetadata getMetadata()
{
return metadata;
}
}

View File

@ -0,0 +1,14 @@
package org.apache.maven.artifact.repository.metadata;
import org.apache.maven.artifact.repository.ArtifactRepository;
public interface RepositoryMetadataManager
{
void get( RepositoryMetadata repositoryMetadata, ArtifactRepository remote, ArtifactRepository local )
throws RepositoryMetadataManagementException;
void put( RepositoryMetadata repositoryMetadata, ArtifactRepository remote )
throws RepositoryMetadataManagementException;
}

View File

@ -42,6 +42,11 @@
<artifactId>maven-settings</artifactId>
<version>2.0-beta-1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-mapping</artifactId>
<version>2.0-beta-1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-registry</artifactId>

View File

@ -39,6 +39,7 @@ public class MBoot
{
String[] builds = new String[]{"maven-model", "maven-settings", "maven-monitor", "maven-plugin-api",
"maven-plugin-descriptor", "maven-artifact", "maven-artifact-manager", "maven-artifact-test",
"maven-plugin-mapping",
"maven-script/maven-script-beanshell", "maven-script/maven-script-marmalade", "maven-project", "maven-profile",
"maven-plugin-registry", "maven-reporting/maven-reporting-api", "maven-core", "maven-archiver",
"maven-plugin-tools/maven-plugin-tools-api", "maven-plugin-tools/maven-plugin-tools-java",
@ -60,6 +61,7 @@ public class MBoot
targetVersions.put( "maven-profile", "1.0.0" );
targetVersions.put( "maven-plugin-registry", "1.0.0" );
targetVersions.put( "maven-plugin-descriptor", "1.0.0" );
targetVersions.put( "maven-plugin-mapping", "1.0.0" );
MODELLO_TARGET_VERSIONS = Collections.unmodifiableMap( targetVersions );
@ -69,6 +71,7 @@ public class MBoot
modelFiles.put( "maven-profile", "profiles.mdo" );
modelFiles.put( "maven-plugin-registry", "plugin-registry.mdo" );
modelFiles.put( "maven-plugin-descriptor", "src/main/mdo/lifecycle.mdo" );
modelFiles.put( "maven-plugin-mapping", "src/main/mdo/plugins.mdo" );
MODELLO_MODEL_FILES = Collections.unmodifiableMap( modelFiles );
}

View File

@ -33,6 +33,7 @@
<goal>xpp3-writer</goal>
<goal>java</goal>
<goal>xpp3-reader</goal>
<goal>xsd</goal>
</goals>
</execution>
</executions>

View File

@ -0,0 +1,58 @@
<project>
<parent>
<artifactId>maven</artifactId>
<groupId>org.apache.maven</groupId>
<version>2.0-beta-1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-mapping</artifactId>
<version>2.0-beta-1-SNAPSHOT</version>
<name>Maven Plugin Mapping</name>
<description>Maven Plugin Mapping</description>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-artifact</artifactId>
<version>2.0-beta-1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-artifact-manager</artifactId>
<version>2.0-beta-1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-model</artifactId>
<version>2.0-beta-1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>plexus</groupId>
<artifactId>plexus-utils</artifactId>
<version>1.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.modello</groupId>
<artifactId>modello-maven-plugin</artifactId>
<version>1.0-alpha-3</version>
<configuration>
<version>1.0.0</version>
<model>src/main/mdo/plugins.mdo</model>
</configuration>
<executions>
<execution>
<goals>
<goal>xpp3-writer</goal>
<goal>java</goal>
<goal>xpp3-reader</goal>
<goal>xsd</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,101 @@
package org.apache.maven.plugin.mapping;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.metadata.RepositoryMetadataManagementException;
import org.apache.maven.artifact.repository.metadata.RepositoryMetadataManager;
import org.apache.maven.plugin.mapping.io.xpp3.PluginMappingXpp3Reader;
import org.apache.maven.plugin.mapping.metadata.PluginMappingMetadata;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Iterator;
import java.util.List;
public class DefaultPluginMappingBuilder
implements MavenPluginMappingBuilder
{
// component requirement
private RepositoryMetadataManager repositoryMetadataManager;
public PluginMappingManager loadPluginMappings( List pluginGroupIds, List pluginRepositories,
ArtifactRepository localRepository )
throws RepositoryMetadataManagementException, PluginMappingManagementException
{
PluginMappingManager mappingManager = new PluginMappingManager();
for ( Iterator it = pluginGroupIds.iterator(); it.hasNext(); )
{
String groupId = (String) it.next();
File mappingFile = resolveMappingMetadata( groupId, pluginRepositories, localRepository );
PluginMap pluginMap = readPluginMap( mappingFile );
mappingManager.addPluginMap( pluginMap );
}
return mappingManager;
}
private PluginMap readPluginMap( File mappingFile ) throws PluginMappingManagementException
{
Reader fileReader = null;
try
{
fileReader = new FileReader( mappingFile );
PluginMappingXpp3Reader mappingReader = new PluginMappingXpp3Reader();
return mappingReader.read(fileReader);
}
catch ( IOException e )
{
throw new PluginMappingManagementException( "Cannot read plugin mappings from: " + mappingFile, e );
}
catch ( XmlPullParserException e )
{
throw new PluginMappingManagementException( "Cannot parse plugin mappings from: " + mappingFile, e );
}
finally
{
IOUtil.close( fileReader );
}
}
private File resolveMappingMetadata( String groupId, List pluginRepositories, ArtifactRepository localRepository )
throws RepositoryMetadataManagementException
{
PluginMappingMetadata metadata = new PluginMappingMetadata( groupId );
RepositoryMetadataManagementException repositoryException = null;
for ( Iterator repoIterator = pluginRepositories.iterator(); repoIterator.hasNext(); )
{
ArtifactRepository repository = (ArtifactRepository) repoIterator.next();
try
{
repositoryMetadataManager.get( metadata, repository, localRepository );
break;
}
catch ( RepositoryMetadataManagementException e )
{
repositoryException = e;
}
}
if ( repositoryException != null )
{
throw repositoryException;
}
return metadata.getFile();
}
}

View File

@ -0,0 +1,15 @@
package org.apache.maven.plugin.mapping;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.metadata.RepositoryMetadataManagementException;
import java.util.List;
public interface MavenPluginMappingBuilder
{
PluginMappingManager loadPluginMappings( List pluginGroupIds, List pluginRepositories,
ArtifactRepository localRepository )
throws RepositoryMetadataManagementException, PluginMappingManagementException;
}

View File

@ -0,0 +1,17 @@
package org.apache.maven.plugin.mapping;
public class PluginMappingManagementException
extends Exception
{
public PluginMappingManagementException( String message, Throwable cause )
{
super( message, cause );
}
public PluginMappingManagementException( String message )
{
super( message );
}
}

View File

@ -0,0 +1,68 @@
package org.apache.maven.plugin.mapping;
import org.apache.maven.model.Plugin;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class PluginMappingManager
{
private List mappings = new ArrayList();
private Map pluginDefinitionsByPrefix = new HashMap();
public void addPluginMap( PluginMap pluginMap )
{
mappings.add( pluginMap );
// flush the cache.
pluginDefinitionsByPrefix = null;
}
public Plugin getByPrefix( String pluginPrefix )
{
synchronized ( this )
{
if ( pluginDefinitionsByPrefix == null )
{
calculatePluginDefinitionsByPrefix();
}
}
return (Plugin) pluginDefinitionsByPrefix.get( pluginPrefix );
}
private void calculatePluginDefinitionsByPrefix()
{
pluginDefinitionsByPrefix = new HashMap();
for ( Iterator it = mappings.iterator(); it.hasNext(); )
{
PluginMap pluginMap = (PluginMap) it.next();
String groupId = pluginMap.getGroupId();
for ( Iterator pluginIterator = pluginMap.getPlugins().iterator(); pluginIterator.hasNext(); )
{
MappedPlugin mapping = (MappedPlugin) pluginIterator.next();
String prefix = mapping.getPrefix();
String artifactId = mapping.getArtifactId();
Plugin plugin = new Plugin();
plugin.setGroupId( groupId );
plugin.setArtifactId( artifactId );
pluginDefinitionsByPrefix.put( prefix, plugin );
}
}
}
}

View File

@ -0,0 +1,36 @@
package org.apache.maven.plugin.mapping.metadata;
import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
import java.io.File;
public class PluginMappingMetadata
implements RepositoryMetadata
{
private static final String PLUGIN_MAPPING_FILE = "plugins.xml";
private final String groupId;
private File metadataFile;
public PluginMappingMetadata( String groupId )
{
this.groupId = groupId;
}
public String getRepositoryPath()
{
return groupId + "/" + PLUGIN_MAPPING_FILE;
}
public void setFile( File metadataFile )
{
this.metadataFile = metadataFile;
}
public File getFile()
{
return metadataFile;
}
}

View File

@ -0,0 +1,59 @@
<model>
<id>plugin-map</id>
<name>PluginMapping</name>
<description>Mappings for searching for a plugin within a particular groupId.</description>
<defaults>
<default>
<key>package</key>
<value>org.apache.maven.plugin.mapping</value>
</default>
</defaults>
<classes>
<class rootElement="true" xml.tagName="mapping">
<name>PluginMap</name>
<version>1.0.0</version>
<description>Root model class, containing various mappings for plugins in this group.</description>
<fields>
<field>
<name>groupId</name>
<version>1.0.0</version>
<type>String</type>
<required>true</required>
<description>The groupId for plugins mapped in this file.</description>
</field>
<field>
<name>plugins</name>
<version>1.0.0</version>
<required>true</required>
<description>The set of plugin mappings</description>
<association>
<type>MappedPlugin</type>
<multiplicity>*</multiplicity>
</association>
</field>
</fields>
</class>
<class xml.tagName="plugin">
<name>MappedPlugin</name>
<version>1.0.0</version>
<description>Mapping information for a single plugin within this group</description>
<comment>NOTE: plugin version is _NOT_ included here, since it is resolved using a separate algorithm.</comment>
<fields>
<field>
<name>prefix</name>
<type>String</type>
<required>true</required>
<version>1.0.0</version>
<description>The plugin invocation prefix (i.e. eclipse for eclipse:eclipse)</description>
</field>
<field>
<name>artifactId</name>
<type>String</type>
<required>true</required>
<version>1.0.0</version>
<description>The plugin artifactId</description>
</field>
</fields>
</class>
</classes>
</model>

View File

@ -180,6 +180,15 @@
<multiplicity>*</multiplicity>
</association>
</field>
<field>
<name>pluginGroups</name>
<version>1.0.0</version>
<description>List of groupIds to search for a plugin when that plugin groupId is not explicitly provided.</description>
<association>
<type>String</type>
<multiplicity>*</multiplicity>
</association>
</field>
</fields>
<codeSegments>
<codeSegment>

View File

@ -34,8 +34,10 @@ public class RuntimeInfo
private String localRepositorySourceLevel = TrackableBase.USER_LEVEL;
private final Settings settings;
private Map pluginGroupIdSourceLevels = new HashMap();
private final Settings settings;
public RuntimeInfo( Settings settings )
{
this.settings = settings;
@ -90,6 +92,25 @@ public class RuntimeInfo
}
}
public void setPluginGroupIdSourceLevel( String pluginGroupId, String sourceLevel )
{
pluginGroupIdSourceLevels.put( pluginGroupId, sourceLevel );
}
public String getSourceLevelForPluginGroupId( String pluginGroupId )
{
String sourceLevel = (String) pluginGroupIdSourceLevels.get( pluginGroupId );
if ( sourceLevel != null )
{
return sourceLevel;
}
else
{
return settings.getSourceLevel();
}
}
public void setLocalRepositorySourceLevel( String localRepoSourceLevel )
{
this.localRepositorySourceLevel = localRepoSourceLevel;

View File

@ -55,6 +55,21 @@ public final class SettingsUtils
}
}
List dominantPluginGroupIds = dominant.getPluginGroups();
List recessivePluginGroupIds = recessive.getPluginGroups();
for ( Iterator it = recessivePluginGroupIds.iterator(); it.hasNext(); )
{
String pluginGroupId = (String) it.next();
if ( !dominantPluginGroupIds.contains( pluginGroupId ) )
{
dominantPluginGroupIds.add( pluginGroupId );
dominant.getRuntimeInfo().setPluginGroupIdSourceLevel( pluginGroupId, recessiveSourceLevel );
}
}
if ( StringUtils.isEmpty( dominant.getLocalRepository() ) )
{
dominant.setLocalRepository( recessive.getLocalRepository() );

View File

@ -0,0 +1,35 @@
package org.apache.maven.settings;
import java.util.List;
import junit.framework.TestCase;
public class SettingsUtilsTest
extends TestCase
{
public void testShouldAppendRecessivePluginGroupIds()
{
Settings dominant = new Settings();
dominant.addPluginGroup( "org.apache.maven.plugins" );
dominant.addPluginGroup( "org.codehaus.modello" );
dominant.setRuntimeInfo(new RuntimeInfo(dominant));
Settings recessive = new Settings();
recessive.addPluginGroup( "org.codehaus.plexus" );
recessive.setRuntimeInfo(new RuntimeInfo(recessive));
SettingsUtils.merge( dominant, recessive, Settings.GLOBAL_LEVEL );
List pluginGroups = dominant.getPluginGroups();
assertNotNull( pluginGroups );
assertEquals( 3, pluginGroups.size() );
assertEquals( "org.apache.maven.plugins", pluginGroups.get( 0 ) );
assertEquals( "org.codehaus.modello", pluginGroups.get( 1 ) );
assertEquals( "org.codehaus.plexus", pluginGroups.get( 2 ) );
}
}