This is an automated email from the ASF dual-hosted git repository.

cstamas pushed a commit to branch MNG-7055-g-level-md-mvn-39x
in repository https://gitbox.apache.org/repos/asf/maven.git

commit 0ddf3be40dd3cb1d9dab4519b9cbf0f9b777c9c0
Author: Tamas Cservenak <ta...@cservenak.net>
AuthorDate: Sun Mar 13 19:07:26 2022 +0100

    [MNG-7055] Fix G level metadata handling (#555)
    
    Maven Artifact Transfer silently prevents group level metadata to reach 
Resolver and causes metadata loss on install/deploy.
    Fix is to "bridge" this from maven-resolver-provider (and core) by reusing 
the actual metadata that
    m-plugin-p:addPluginArtifactMetadata mojo adds, but m-a-t filters out.
    
    This is backport of commit d141957ff5a3c08ae53c68e4ba19b49055f717c4 to 
maven-3.9.x branch.
---
 maven-compat/pom.xml                               |   5 +
 .../artifact/deployer/ArtifactDeployerTest.java    |  36 ++++--
 .../artifact/installer/ArtifactInstallerTest.java  |  28 ++++-
 .../DefaultPluginsMetadataInfoProvider.java        | 137 +++++++++++++++++++++
 .../resources/META-INF/plexus/default-bindings.xml |  28 ++---
 .../maven/repository/internal/PluginsMetadata.java | 117 ++++++++++++++++++
 .../internal/PluginsMetadataGenerator.java         | 130 +++++++++++++++++++
 .../internal/PluginsMetadataGeneratorFactory.java  |  67 ++++++++++
 .../internal/PluginsMetadataInfoProvider.java      |  47 +++++++
 9 files changed, 567 insertions(+), 28 deletions(-)

diff --git a/maven-compat/pom.xml b/maven-compat/pom.xml
index 4f79ac8..ed7bce8 100644
--- a/maven-compat/pom.xml
+++ b/maven-compat/pom.xml
@@ -100,6 +100,11 @@ under the License.
     </dependency>
 
     <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>org.apache.maven.wagon</groupId>
       <artifactId>wagon-file</artifactId>
       <scope>test</scope>
diff --git 
a/maven-compat/src/test/java/org/apache/maven/artifact/deployer/ArtifactDeployerTest.java
 
b/maven-compat/src/test/java/org/apache/maven/artifact/deployer/ArtifactDeployerTest.java
index f929f48..ed0a43c 100644
--- 
a/maven-compat/src/test/java/org/apache/maven/artifact/deployer/ArtifactDeployerTest.java
+++ 
b/maven-compat/src/test/java/org/apache/maven/artifact/deployer/ArtifactDeployerTest.java
@@ -24,8 +24,12 @@ import java.io.File;
 import org.apache.maven.artifact.AbstractArtifactComponentTestCase;
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.session.scope.internal.SessionScope;
 import org.codehaus.plexus.util.FileUtils;
 
+import static org.mockito.Mockito.mock;
+
 /**
  * @author <a href="mailto:ja...@maven.org";>Jason van Zyl</a>
  */
@@ -34,12 +38,16 @@ public class ArtifactDeployerTest
 {
     private ArtifactDeployer artifactDeployer;
 
+    private SessionScope sessionScope;
+
     protected void setUp()
         throws Exception
     {
         super.setUp();
 
         artifactDeployer = (ArtifactDeployer) lookup( ArtifactDeployer.ROLE );
+
+        sessionScope = lookup( SessionScope.class );
     }
 
     protected String component()
@@ -50,18 +58,28 @@ public class ArtifactDeployerTest
     public void testArtifactInstallation()
         throws Exception
     {
-        String artifactBasedir = new File( getBasedir(), 
"src/test/resources/artifact-install" ).getAbsolutePath();
+        sessionScope.enter();
+        try
+        {
+            sessionScope.seed(MavenSession.class, mock(MavenSession.class));
+
+            String artifactBasedir = new File( getBasedir(), 
"src/test/resources/artifact-install" ).getAbsolutePath();
 
-        Artifact artifact = createArtifact( "artifact", "1.0" );
+            Artifact artifact = createArtifact( "artifact", "1.0" );
 
-        File file = new File( artifactBasedir, "artifact-1.0.jar" );
-        assertEquals( "dummy", FileUtils.fileRead( file, "UTF-8" ).trim() );
+            File file = new File( artifactBasedir, "artifact-1.0.jar" );
+            assertEquals( "dummy", FileUtils.fileRead( file, "UTF-8" ).trim() 
);
 
-        artifactDeployer.deploy( file, artifact, remoteRepository(), 
localRepository() );
+            artifactDeployer.deploy( file, artifact, remoteRepository(), 
localRepository() );
 
-        ArtifactRepository remoteRepository = remoteRepository();
-        File deployedFile = new File( remoteRepository.getBasedir(), 
remoteRepository.pathOf( artifact ) );
-        assertTrue( deployedFile.exists() );
-        assertEquals( "dummy", FileUtils.fileRead( deployedFile, "UTF-8" 
).trim() );
+            ArtifactRepository remoteRepository = remoteRepository();
+            File deployedFile = new File( remoteRepository.getBasedir(), 
remoteRepository.pathOf( artifact ) );
+            assertTrue( deployedFile.exists() );
+            assertEquals( "dummy", FileUtils.fileRead( deployedFile, "UTF-8" 
).trim() );
+        }
+        finally
+        {
+            sessionScope.exit();
+        }
     }
 }
\ No newline at end of file
diff --git 
a/maven-compat/src/test/java/org/apache/maven/artifact/installer/ArtifactInstallerTest.java
 
b/maven-compat/src/test/java/org/apache/maven/artifact/installer/ArtifactInstallerTest.java
index 21bfb2b..66ba9e9 100644
--- 
a/maven-compat/src/test/java/org/apache/maven/artifact/installer/ArtifactInstallerTest.java
+++ 
b/maven-compat/src/test/java/org/apache/maven/artifact/installer/ArtifactInstallerTest.java
@@ -23,6 +23,10 @@ import java.io.File;
 
 import org.apache.maven.artifact.AbstractArtifactComponentTestCase;
 import org.apache.maven.artifact.Artifact;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.session.scope.internal.SessionScope;
+
+import static org.mockito.Mockito.mock;
 
 /**
  * @author <a href="mailto:ja...@maven.org";>Jason van Zyl</a>
@@ -32,12 +36,16 @@ public class ArtifactInstallerTest
 {
     private ArtifactInstaller artifactInstaller;
 
+    private SessionScope sessionScope;
+
     protected void setUp()
         throws Exception
     {
         super.setUp();
 
         artifactInstaller = (ArtifactInstaller) lookup( ArtifactInstaller.ROLE 
);
+
+        sessionScope = lookup( SessionScope.class );
     }
 
     protected String component()
@@ -48,14 +56,24 @@ public class ArtifactInstallerTest
     public void testArtifactInstallation()
         throws Exception
     {
-        String artifactBasedir = new File( getBasedir(), 
"src/test/resources/artifact-install" ).getAbsolutePath();
+        sessionScope.enter();
+        try
+        {
+            sessionScope.seed(MavenSession.class, mock(MavenSession.class));
+
+            String artifactBasedir = new File( getBasedir(), 
"src/test/resources/artifact-install" ).getAbsolutePath();
 
-        Artifact artifact = createArtifact( "artifact", "1.0" );
+            Artifact artifact = createArtifact( "artifact", "1.0" );
 
-        File source = new File( artifactBasedir, "artifact-1.0.jar" );
+            File source = new File( artifactBasedir, "artifact-1.0.jar" );
 
-        artifactInstaller.install( source, artifact, localRepository() );
+            artifactInstaller.install( source, artifact, localRepository() );
 
-        assertLocalArtifactPresent( artifact );
+            assertLocalArtifactPresent( artifact );
+        }
+        finally
+        {
+            sessionScope.exit();
+        }
     }
 }
\ No newline at end of file
diff --git 
a/maven-core/src/main/java/org/apache/maven/execution/infoproviders/DefaultPluginsMetadataInfoProvider.java
 
b/maven-core/src/main/java/org/apache/maven/execution/infoproviders/DefaultPluginsMetadataInfoProvider.java
new file mode 100644
index 0000000..616a3a8
--- /dev/null
+++ 
b/maven-core/src/main/java/org/apache/maven/execution/infoproviders/DefaultPluginsMetadataInfoProvider.java
@@ -0,0 +1,137 @@
+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;
+    }
+}
diff --git a/maven-core/src/main/resources/META-INF/plexus/default-bindings.xml 
b/maven-core/src/main/resources/META-INF/plexus/default-bindings.xml
index 4a303db..e35f931 100644
--- a/maven-core/src/main/resources/META-INF/plexus/default-bindings.xml
+++ b/maven-core/src/main/resources/META-INF/plexus/default-bindings.xml
@@ -41,10 +41,10 @@ Mappings to default lifecycle, specific for each packaging.
             <!-- START SNIPPET: pom-lifecycle -->
             <phases>
               <install>
-                org.apache.maven.plugins:maven-install-plugin:2.4:install
+                org.apache.maven.plugins:maven-install-plugin:3.0.0-M1:install
               </install>
               <deploy>
-                org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
+                org.apache.maven.plugins:maven-deploy-plugin:3.0.0-M2:deploy
               </deploy>
             </phases>
             <!-- END SNIPPET: pom-lifecycle -->
@@ -85,10 +85,10 @@ Mappings to default lifecycle, specific for each packaging.
                 org.apache.maven.plugins:maven-jar-plugin:2.4:jar
               </package>
               <install>
-                org.apache.maven.plugins:maven-install-plugin:2.4:install
+                org.apache.maven.plugins:maven-install-plugin:3.0.0-M1:install
               </install>
               <deploy>
-                org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
+                org.apache.maven.plugins:maven-deploy-plugin:3.0.0-M2:deploy
               </deploy>
             </phases>
             <!-- END SNIPPET: jar-lifecycle -->
@@ -129,10 +129,10 @@ Mappings to default lifecycle, specific for each 
packaging.
                 org.apache.maven.plugins:maven-ejb-plugin:2.3:ejb
               </package>
               <install>
-                org.apache.maven.plugins:maven-install-plugin:2.4:install
+                org.apache.maven.plugins:maven-install-plugin:3.0.0-M1:install
               </install>
               <deploy>
-                org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
+                org.apache.maven.plugins:maven-deploy-plugin:3.0.0-M2:deploy
               </deploy>
             </phases>
             <!-- END SNIPPET: ejb-lifecycle -->
@@ -177,10 +177,10 @@ Mappings to default lifecycle, specific for each 
packaging.
                 
org.apache.maven.plugins:maven-plugin-plugin:3.2:addPluginArtifactMetadata
               </package>
               <install>
-                org.apache.maven.plugins:maven-install-plugin:2.4:install
+                org.apache.maven.plugins:maven-install-plugin:3.0.0-M1:install
               </install>
               <deploy>
-                org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
+                org.apache.maven.plugins:maven-deploy-plugin:3.0.0-M2:deploy
               </deploy>
             </phases>
             <!-- END SNIPPET: maven-plugin-lifecycle -->
@@ -221,10 +221,10 @@ Mappings to default lifecycle, specific for each 
packaging.
                 org.apache.maven.plugins:maven-war-plugin:2.2:war
               </package>
               <install>
-                org.apache.maven.plugins:maven-install-plugin:2.4:install
+                org.apache.maven.plugins:maven-install-plugin:3.0.0-M1:install
               </install>
               <deploy>
-                org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
+                org.apache.maven.plugins:maven-deploy-plugin:3.0.0-M2:deploy
               </deploy>
             </phases>
             <!-- END SNIPPET: war-lifecycle -->
@@ -256,10 +256,10 @@ Mappings to default lifecycle, specific for each 
packaging.
                 org.apache.maven.plugins:maven-ear-plugin:2.8:ear
               </package>
               <install>
-                org.apache.maven.plugins:maven-install-plugin:2.4:install
+                org.apache.maven.plugins:maven-install-plugin:3.0.0-M1:install
               </install>
               <deploy>
-                org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
+                org.apache.maven.plugins:maven-deploy-plugin:3.0.0-M2:deploy
               </deploy>
             </phases>
             <!-- END SNIPPET: ear-lifecycle -->
@@ -300,10 +300,10 @@ Mappings to default lifecycle, specific for each 
packaging.
                 org.apache.maven.plugins:maven-rar-plugin:2.2:rar
               </package>
               <install>
-                org.apache.maven.plugins:maven-install-plugin:2.4:install
+                org.apache.maven.plugins:maven-install-plugin:3.0.0-M1:install
               </install>
               <deploy>
-                org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
+                org.apache.maven.plugins:maven-deploy-plugin:3.0.0-M2:deploy
               </deploy>
             </phases>
             <!-- END SNIPPET: rar-lifecycle -->
diff --git 
a/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/PluginsMetadata.java
 
b/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/PluginsMetadata.java
new file mode 100644
index 0000000..7a6c45a
--- /dev/null
+++ 
b/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/PluginsMetadata.java
@@ -0,0 +1,117 @@
+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 java.io.File;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.LinkedHashMap;
+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.
+ */
+final class PluginsMetadata
+    extends MavenMetadata
+{
+    private final PluginInfo pluginInfo;
+
+    PluginsMetadata( PluginInfo pluginInfo, Date timestamp )
+    {
+        super( createRepositoryMetadata( pluginInfo ), null, timestamp );
+        this.pluginInfo = pluginInfo;
+    }
+
+    PluginsMetadata( PluginInfo pluginInfo, File file, Date timestamp )
+    {
+        super( createRepositoryMetadata( pluginInfo ), file, timestamp );
+        this.pluginInfo = pluginInfo;
+    }
+
+    private static Metadata createRepositoryMetadata( PluginInfo pluginInfo )
+    {
+        Metadata result = new Metadata();
+        Plugin plugin = new Plugin();
+        plugin.setPrefix( pluginInfo.getPluginPrefix() );
+        plugin.setArtifactId( pluginInfo.getPluginArtifactId() );
+        plugin.setName( pluginInfo.getPluginName() );
+        result.getPlugins().add( plugin );
+        return result;
+    }
+
+    @Override
+    protected void merge( Metadata recessive )
+    {
+        List<Plugin> recessivePlugins = recessive.getPlugins();
+        List<Plugin> plugins = metadata.getPlugins();
+        if ( !plugins.isEmpty() )
+        {
+            LinkedHashMap<String, Plugin> mergedPlugins = new 
LinkedHashMap<>();
+            recessivePlugins.forEach( p -> mergedPlugins.put( p.getPrefix(), p 
) );
+            plugins.forEach( p -> mergedPlugins.put( p.getPrefix(), p ) );
+            metadata.setPlugins( new ArrayList<>( mergedPlugins.values() ) );
+        }
+    }
+
+    public Object getKey()
+    {
+        return getGroupId();
+    }
+
+    public static Object getKey( Artifact artifact )
+    {
+        return artifact.getGroupId();
+    }
+
+    @Override
+    public MavenMetadata setFile( File file )
+    {
+        return new PluginsMetadata( pluginInfo, file, timestamp );
+    }
+
+    @Override
+    public String getGroupId()
+    {
+        return pluginInfo.getPluginGroupId();
+    }
+
+    @Override
+    public String getArtifactId()
+    {
+        return "";
+    }
+
+    @Override
+    public String getVersion()
+    {
+        return "";
+    }
+
+    @Override
+    public Nature getNature()
+    {
+        return Nature.RELEASE_OR_SNAPSHOT;
+    }
+}
diff --git 
a/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/PluginsMetadataGenerator.java
 
b/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/PluginsMetadataGenerator.java
new file mode 100644
index 0000000..4f35568
--- /dev/null
+++ 
b/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/PluginsMetadataGenerator.java
@@ -0,0 +1,130 @@
+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 java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import 
org.apache.maven.repository.internal.PluginsMetadataInfoProvider.PluginInfo;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.deployment.DeployRequest;
+import org.eclipse.aether.impl.MetadataGenerator;
+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.
+ */
+class PluginsMetadataGenerator
+    implements MetadataGenerator
+{
+    private final PluginsMetadataInfoProvider pluginsMetadataInfoProvider;
+
+    private final Map<Object, PluginsMetadata> plugins;
+
+    private final Map<Object, PluginsMetadata> processedPlugins;
+
+    private final Date timestamp;
+
+    PluginsMetadataGenerator( PluginsMetadataInfoProvider 
pluginsMetadataInfoProvider,
+                              RepositorySystemSession session,
+                              InstallRequest request )
+    {
+        this( pluginsMetadataInfoProvider, session, request.getMetadata() );
+    }
+
+    PluginsMetadataGenerator( PluginsMetadataInfoProvider 
pluginsMetadataInfoProvider,
+                              RepositorySystemSession session,
+                              DeployRequest request )
+    {
+        this( pluginsMetadataInfoProvider, session, request.getMetadata() );
+    }
+
+    private PluginsMetadataGenerator( PluginsMetadataInfoProvider 
pluginsMetadataInfoProvider,
+                                      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" );
+
+        /*
+         * NOTE: This should be considered a quirk to support interop with 
Maven's legacy ArtifactDeployer which
+         * processes one artifact at a time and hence cannot associate the 
artifacts from the same project to use the
+         * same version index. Allowing the caller to pass in metadata from a 
previous deployment allows to re-establish
+         * the association between the artifacts of the same project.
+         */
+        for ( Iterator<? extends Metadata> it = metadatas.iterator(); 
it.hasNext(); )
+        {
+            Metadata metadata = it.next();
+            if ( metadata instanceof PluginsMetadata )
+            {
+                it.remove();
+                PluginsMetadata pluginMetadata = ( PluginsMetadata ) metadata;
+                processedPlugins.put( pluginMetadata.getKey(), pluginMetadata 
);
+            }
+        }
+    }
+
+    @Override
+    public Collection<? extends Metadata> prepare( Collection<? extends 
Artifact> artifacts )
+    {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public Artifact transformArtifact( Artifact artifact )
+    {
+        return artifact;
+    }
+
+    @Override
+    public Collection<? extends Metadata> finish( Collection<? extends 
Artifact> artifacts )
+    {
+        for ( Artifact artifact : artifacts )
+        {
+            PluginInfo pluginInfo = pluginsMetadataInfoProvider.getPluginInfo( 
artifact );
+            if ( pluginInfo != null )
+            {
+                Object key = PluginsMetadata.getKey( artifact );
+                if ( processedPlugins.get( key ) == null )
+                {
+                    PluginsMetadata pluginMetadata = plugins.get( key );
+                    if ( pluginMetadata == null )
+                    {
+                        pluginMetadata = new PluginsMetadata( pluginInfo, 
timestamp );
+                        plugins.put( key, pluginMetadata );
+                    }
+                }
+            }
+        }
+
+        return plugins.values();
+    }
+}
diff --git 
a/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/PluginsMetadataGeneratorFactory.java
 
b/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/PluginsMetadataGeneratorFactory.java
new file mode 100644
index 0000000..19d499b
--- /dev/null
+++ 
b/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/PluginsMetadataGeneratorFactory.java
@@ -0,0 +1,67 @@
+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 javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.deployment.DeployRequest;
+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.
+ */
+@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 );
+    }
+
+    @Override
+    public MetadataGenerator newInstance( RepositorySystemSession session, 
DeployRequest request )
+    {
+        return new PluginsMetadataGenerator( pluginsMetadataInfoProvider, 
session, request );
+    }
+
+    @Override
+    public float getPriority()
+    {
+        return 5;
+    }
+}
diff --git 
a/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/PluginsMetadataInfoProvider.java
 
b/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/PluginsMetadataInfoProvider.java
new file mode 100644
index 0000000..806fa46
--- /dev/null
+++ 
b/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/PluginsMetadataInfoProvider.java
@@ -0,0 +1,47 @@
+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 );
+}

Reply via email to