Maven-3.9.x Simplify maven-plugin metadata handling (#807)

This commit is contained in:
Tamas Cservenak 2022-10-11 14:11:34 +02:00 committed by GitHub
parent a7a5b8169b
commit 5136a5ea81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 123 additions and 255 deletions

View File

@ -1,137 +0,0 @@
package org.apache.maven.execution.infoproviders;
/*
* 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.Objects;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Singleton;
import org.apache.maven.artifact.repository.metadata.Metadata;
import org.apache.maven.artifact.repository.metadata.Plugin;
import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.project.MavenProject;
import org.apache.maven.repository.internal.PluginsMetadataInfoProvider;
import org.apache.maven.repository.legacy.metadata.ArtifactMetadata;
import org.eclipse.aether.artifact.Artifact;
import static java.util.Objects.requireNonNull;
/**
* Default implementation of {@link PluginsMetadataInfoProvider}.
*/
@Named
@Singleton
public class DefaultPluginsMetadataInfoProvider
implements PluginsMetadataInfoProvider
{
private final Provider<MavenSession> mavenSessionProvider;
@Inject
public DefaultPluginsMetadataInfoProvider( final Provider<MavenSession> mavenSessionProvider )
{
this.mavenSessionProvider = requireNonNull( mavenSessionProvider );
}
@Override
public PluginInfo getPluginInfo( final Artifact artifact )
{
MavenSession mavenSession = mavenSessionProvider.get();
if ( mavenSession != null )
{
MavenProject mavenProject = searchForProject( mavenSession, artifact );
if ( mavenProject != null && "maven-plugin".equals( mavenProject.getPackaging() ) )
{
Plugin plugin = searchForPluginGroupLevelRepositoryMetadata( mavenProject );
if ( plugin != null )
{
return new PluginInfo()
{
@Override
public String getPluginGroupId()
{
return artifact.getGroupId();
}
@Override
public String getPluginArtifactId()
{
return artifact.getArtifactId();
}
@Override
public String getPluginPrefix()
{
return plugin.getPrefix();
}
@Override
public String getPluginName()
{
return plugin.getName();
}
};
}
}
}
return null;
}
private MavenProject searchForProject( MavenSession mavenSession, Artifact artifact )
{
for ( MavenProject mavenProject : mavenSession.getProjects() )
{
if ( mavenProject.getArtifact() != null
&& Objects.equals( mavenProject.getGroupId(), artifact.getGroupId() )
&& Objects.equals( mavenProject.getArtifactId(), artifact.getArtifactId() ) )
{
return mavenProject;
}
}
return null;
}
private Plugin searchForPluginGroupLevelRepositoryMetadata( MavenProject mavenProject )
{
org.apache.maven.artifact.Artifact projectArtifact = mavenProject.getArtifact();
for ( ArtifactMetadata artifactMetadata : projectArtifact.getMetadataList() )
{
if ( artifactMetadata instanceof RepositoryMetadata )
{
RepositoryMetadata repositoryMetadata = (RepositoryMetadata) artifactMetadata;
Metadata metadata = repositoryMetadata.getMetadata();
for ( Plugin plugin : metadata.getPlugins() )
{
if ( Objects.equals( plugin.getArtifactId(), mavenProject.getArtifactId() ) )
{
return plugin;
}
}
}
}
return null;
}
}

View File

@ -33,7 +33,7 @@ import org.apache.maven.artifact.repository.metadata.Versioning;
import org.eclipse.aether.artifact.Artifact;
/**
* @author Benjamin Bentmann
* Maven local GAV level metadata.
*/
final class LocalSnapshotMetadata
extends MavenMetadata

View File

@ -33,10 +33,12 @@ import org.eclipse.aether.metadata.Metadata;
import org.eclipse.aether.util.ConfigUtils;
/**
* @author Benjamin Bentmann
* Maven local GAV level metadata generator.
* <p>
* Local snapshot metadata contains non-transformed snapshot version.
*/
class LocalSnapshotMetadataGenerator
implements MetadataGenerator
implements MetadataGenerator
{
private Map<Object, LocalSnapshotMetadata> snapshots;

View File

@ -27,15 +27,32 @@ import java.util.List;
import org.apache.maven.artifact.repository.metadata.Metadata;
import org.apache.maven.artifact.repository.metadata.Plugin;
import org.apache.maven.repository.internal.PluginsMetadataInfoProvider.PluginInfo;
import org.eclipse.aether.artifact.Artifact;
/**
* Plugin G level metadata.
* Maven G level metadata.
*/
final class PluginsMetadata
extends MavenMetadata
{
static final class PluginInfo
{
final String groupId;
private final String artifactId;
private final String goalPrefix;
private final String name;
PluginInfo( String groupId, String artifactId, String goalPrefix, String name )
{
this.groupId = groupId;
this.artifactId = artifactId;
this.goalPrefix = goalPrefix;
this.name = name;
}
}
private final PluginInfo pluginInfo;
PluginsMetadata( PluginInfo pluginInfo, Date timestamp )
@ -54,9 +71,9 @@ final class PluginsMetadata
{
Metadata result = new Metadata();
Plugin plugin = new Plugin();
plugin.setPrefix( pluginInfo.getPluginPrefix() );
plugin.setArtifactId( pluginInfo.getPluginArtifactId() );
plugin.setName( pluginInfo.getPluginName() );
plugin.setPrefix( pluginInfo.goalPrefix );
plugin.setArtifactId( pluginInfo.artifactId );
plugin.setName( pluginInfo.name );
result.getPlugins().add( plugin );
return result;
}
@ -75,16 +92,6 @@ final class PluginsMetadata
}
}
public Object getKey()
{
return getGroupId();
}
public static Object getKey( Artifact artifact )
{
return artifact.getGroupId();
}
@Override
public MavenMetadata setFile( File file )
{
@ -94,7 +101,7 @@ final class PluginsMetadata
@Override
public String getGroupId()
{
return pluginInfo.getPluginGroupId();
return pluginInfo.groupId;
}
@Override

View File

@ -19,14 +19,22 @@ package org.apache.maven.repository.internal;
* under the License.
*/
import java.io.Reader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import org.apache.maven.repository.internal.PluginsMetadataInfoProvider.PluginInfo;
import org.apache.maven.repository.internal.PluginsMetadata.PluginInfo;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.deployment.DeployRequest;
@ -35,42 +43,35 @@ import org.eclipse.aether.installation.InstallRequest;
import org.eclipse.aether.metadata.Metadata;
import org.eclipse.aether.util.ConfigUtils;
import static java.util.Objects.requireNonNull;
/**
* Plugin G level metadata.
* Maven G level metadata generator.
* <p>
* Plugin metadata contains G level list of "prefix" to A mapping for plugins present under this G.
*/
class PluginsMetadataGenerator
implements MetadataGenerator
implements MetadataGenerator
{
private final PluginsMetadataInfoProvider pluginsMetadataInfoProvider;
private final Map<Object, PluginsMetadata> plugins;
private static final String PLUGIN_DESCRIPTOR_LOCATION = "META-INF/maven/plugin.xml";
private final Map<Object, PluginsMetadata> processedPlugins;
private final Date timestamp;
PluginsMetadataGenerator( PluginsMetadataInfoProvider pluginsMetadataInfoProvider,
RepositorySystemSession session,
PluginsMetadataGenerator( RepositorySystemSession session,
InstallRequest request )
{
this( pluginsMetadataInfoProvider, session, request.getMetadata() );
this( session, request.getMetadata() );
}
PluginsMetadataGenerator( PluginsMetadataInfoProvider pluginsMetadataInfoProvider,
RepositorySystemSession session,
PluginsMetadataGenerator( RepositorySystemSession session,
DeployRequest request )
{
this( pluginsMetadataInfoProvider, session, request.getMetadata() );
this( session, request.getMetadata() );
}
private PluginsMetadataGenerator( PluginsMetadataInfoProvider pluginsMetadataInfoProvider,
RepositorySystemSession session,
private PluginsMetadataGenerator( RepositorySystemSession session,
Collection<? extends Metadata> metadatas )
{
this.pluginsMetadataInfoProvider = requireNonNull( pluginsMetadataInfoProvider );
this.plugins = new LinkedHashMap<>();
this.processedPlugins = new LinkedHashMap<>();
this.timestamp = (Date) ConfigUtils.getObject( session, new Date(), "maven.startTime" );
@ -86,8 +87,8 @@ class PluginsMetadataGenerator
if ( metadata instanceof PluginsMetadata )
{
it.remove();
PluginsMetadata pluginMetadata = ( PluginsMetadata ) metadata;
processedPlugins.put( pluginMetadata.getKey(), pluginMetadata );
PluginsMetadata pluginMetadata = (PluginsMetadata) metadata;
processedPlugins.put( pluginMetadata.getGroupId(), pluginMetadata );
}
}
}
@ -107,12 +108,13 @@ class PluginsMetadataGenerator
@Override
public Collection<? extends Metadata> finish( Collection<? extends Artifact> artifacts )
{
LinkedHashMap<String, PluginsMetadata> plugins = new LinkedHashMap<>();
for ( Artifact artifact : artifacts )
{
PluginInfo pluginInfo = pluginsMetadataInfoProvider.getPluginInfo( artifact );
PluginInfo pluginInfo = extractPluginInfo( artifact );
if ( pluginInfo != null )
{
Object key = PluginsMetadata.getKey( artifact );
String key = pluginInfo.groupId;
if ( processedPlugins.get( key ) == null )
{
PluginsMetadata pluginMetadata = plugins.get( key );
@ -124,7 +126,50 @@ class PluginsMetadataGenerator
}
}
}
return plugins.values();
}
private PluginInfo extractPluginInfo( Artifact artifact )
{
// sanity: jar, no classifier and file exists
if ( artifact != null
&& "jar".equals( artifact.getExtension() )
&& "".equals( artifact.getClassifier() )
&& artifact.getFile() != null )
{
Path artifactPath = artifact.getFile().toPath();
if ( Files.isRegularFile( artifactPath ) )
{
try ( JarFile artifactJar = new JarFile( artifactPath.toFile(), false ) )
{
ZipEntry pluginDescriptorEntry = artifactJar.getEntry( PLUGIN_DESCRIPTOR_LOCATION );
if ( pluginDescriptorEntry != null )
{
try ( Reader reader = ReaderFactory.newXmlReader(
artifactJar.getInputStream( pluginDescriptorEntry ) ) )
{
// Note: using DOM instead of use of
// org.apache.maven.plugin.descriptor.PluginDescriptor
// as it would pull in dependency on:
// - maven-plugin-api (for model)
// - Plexus Container (for model supporting classes and exceptions)
Xpp3Dom root = Xpp3DomBuilder.build( reader );
String groupId = root.getChild( "groupId" ).getValue();
String artifactId = root.getChild( "artifactId" ).getValue();
String goalPrefix = root.getChild( "goalPrefix" ).getValue();
String name = root.getChild( "name" ).getValue();
return new PluginInfo( groupId, artifactId, goalPrefix, name );
}
}
}
catch ( Exception e )
{
// here we can have: IO. ZIP or Plexus Conf Ex: but we should not interfere with user intent
}
}
}
return null;
}
}

View File

@ -19,7 +19,6 @@ package org.apache.maven.repository.internal;
* under the License.
*/
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
@ -29,39 +28,30 @@ import org.eclipse.aether.impl.MetadataGenerator;
import org.eclipse.aether.impl.MetadataGeneratorFactory;
import org.eclipse.aether.installation.InstallRequest;
import static java.util.Objects.requireNonNull;
/**
* Plugin G level metadata.
* Maven G level metadata generator factory.
*/
@Named( "plugins" )
@Singleton
public class PluginsMetadataGeneratorFactory
implements MetadataGeneratorFactory
{
private final PluginsMetadataInfoProvider pluginsMetadataInfoProvider;
@Inject
public PluginsMetadataGeneratorFactory( PluginsMetadataInfoProvider pluginsMetadataInfoProvider )
{
this.pluginsMetadataInfoProvider = requireNonNull( pluginsMetadataInfoProvider );
}
@Override
public MetadataGenerator newInstance( RepositorySystemSession session, InstallRequest request )
{
return new PluginsMetadataGenerator( pluginsMetadataInfoProvider, session, request );
return new PluginsMetadataGenerator( session, request );
}
@Override
public MetadataGenerator newInstance( RepositorySystemSession session, DeployRequest request )
{
return new PluginsMetadataGenerator( pluginsMetadataInfoProvider, session, request );
return new PluginsMetadataGenerator( session, request );
}
@SuppressWarnings( "checkstyle:magicnumber" )
@Override
public float getPriority()
{
return 5;
return 10; // G level MD should be deployed as 3rd MD
}
}

View File

@ -1,47 +0,0 @@
package org.apache.maven.repository.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.eclipse.aether.artifact.Artifact;
/**
* Plugin G level metadata provider.
*/
public interface PluginsMetadataInfoProvider
{
/**
* The required data for G level metadata.
*/
interface PluginInfo
{
String getPluginGroupId();
String getPluginArtifactId();
String getPluginPrefix();
String getPluginName();
}
/**
* Returns {@link PluginInfo} corresponding for passed in {@link Artifact}, or {@code null}.
*/
PluginInfo getPluginInfo( Artifact artifact );
}

View File

@ -36,7 +36,7 @@ import org.apache.maven.artifact.repository.metadata.Versioning;
import org.eclipse.aether.artifact.Artifact;
/**
* @author Benjamin Bentmann
* Maven remote GAV level metadata.
*/
final class RemoteSnapshotMetadata
extends MavenSnapshotMetadata

View File

@ -33,10 +33,12 @@ import org.eclipse.aether.metadata.Metadata;
import org.eclipse.aether.util.ConfigUtils;
/**
* @author Benjamin Bentmann
* Maven remote GAV level metadata generator.
* <p>
* Remote snapshot metadata converts artifact on-the-fly to use timestamped snapshot version, and enlist it accordingly.
*/
class RemoteSnapshotMetadataGenerator
implements MetadataGenerator
implements MetadataGenerator
{
private final Map<Object, RemoteSnapshotMetadata> snapshots;

View File

@ -29,27 +29,29 @@ import org.eclipse.aether.impl.MetadataGeneratorFactory;
import org.eclipse.aether.installation.InstallRequest;
/**
* @author Benjamin Bentmann
* Maven GAV level metadata generator factory.
*/
@Named( "snapshot" )
@Singleton
public class SnapshotMetadataGeneratorFactory
implements MetadataGeneratorFactory
{
@Override
public MetadataGenerator newInstance( RepositorySystemSession session, InstallRequest request )
{
return new LocalSnapshotMetadataGenerator( session, request );
}
@Override
public MetadataGenerator newInstance( RepositorySystemSession session, DeployRequest request )
{
return new RemoteSnapshotMetadataGenerator( session, request );
}
@SuppressWarnings( "checkstyle:magicnumber" )
@Override
public float getPriority()
{
return 10;
return 30; // GAV level metadata should be deployed 1st MD
}
}

View File

@ -31,7 +31,7 @@ import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.ArtifactProperties;
/**
* @author Benjamin Bentmann
* Maven GA level metadata.
*/
final class VersionsMetadata
extends MavenMetadata

View File

@ -35,7 +35,9 @@ import org.eclipse.aether.metadata.Metadata;
import org.eclipse.aether.util.ConfigUtils;
/**
* @author Benjamin Bentmann
* Maven GA level metadata generator.
*
* Version metadata contains list of existing baseVersions within this GA.
*/
class VersionsMetadataGenerator
implements MetadataGenerator

View File

@ -29,27 +29,29 @@ import org.eclipse.aether.impl.MetadataGeneratorFactory;
import org.eclipse.aether.installation.InstallRequest;
/**
* @author Benjamin Bentmann
* Maven GA level metadata generator factory.
*/
@Named( "versions" )
@Singleton
public class VersionsMetadataGeneratorFactory
implements MetadataGeneratorFactory
{
@Override
public MetadataGenerator newInstance( RepositorySystemSession session, InstallRequest request )
{
return new VersionsMetadataGenerator( session, request );
}
@Override
public MetadataGenerator newInstance( RepositorySystemSession session, DeployRequest request )
{
return new VersionsMetadataGenerator( session, request );
}
@SuppressWarnings( "checkstyle:magicnumber" )
@Override
public float getPriority()
{
return 5;
return 20; // GA level metadata should be deployed 2nd MD
}
}