2626import java .nio .file .Files ;
2727import java .util .ArrayList ;
2828import java .util .Collections ;
29- import java .util .HashSet ;
3029import java .util .LinkedHashMap ;
3130import java .util .List ;
3231import java .util .Map ;
3332import java .util .Set ;
33+ import java .util .stream .Collectors ;
34+ import java .util .stream .Stream ;
3435
3536import org .apache .maven .artifact .repository .metadata .Metadata ;
3637import org .apache .maven .artifact .repository .metadata .io .MetadataReader ;
38+ import org .apache .maven .model .Build ;
39+ import org .apache .maven .model .Model ;
40+ import org .apache .maven .model .Plugin ;
41+ import org .apache .maven .model .PluginManagement ;
42+ import org .apache .maven .plugin .BuildPluginManager ;
43+ import org .apache .maven .plugin .descriptor .PluginDescriptor ;
3744import org .apache .maven .plugin .prefix .NoPluginFoundForPrefixException ;
3845import org .apache .maven .plugin .prefix .PluginPrefixRequest ;
3946import org .apache .maven .plugin .prefix .PluginPrefixResolver ;
@@ -65,11 +72,14 @@ public class DefaultPluginPrefixResolver implements PluginPrefixResolver {
6572 private static final String REPOSITORY_CONTEXT = org .apache .maven .api .services .RequestTrace .CONTEXT_PLUGIN ;
6673
6774 private final Logger logger = LoggerFactory .getLogger (getClass ());
75+ private final BuildPluginManager pluginManager ;
6876 private final RepositorySystem repositorySystem ;
6977 private final MetadataReader metadataReader ;
7078
7179 @ Inject
72- public DefaultPluginPrefixResolver (RepositorySystem repositorySystem , MetadataReader metadataReader ) {
80+ public DefaultPluginPrefixResolver (
81+ BuildPluginManager pluginManager , RepositorySystem repositorySystem , MetadataReader metadataReader ) {
82+ this .pluginManager = pluginManager ;
7383 this .repositorySystem = repositorySystem ;
7484 this .metadataReader = metadataReader ;
7585 }
@@ -78,33 +88,37 @@ public DefaultPluginPrefixResolver(RepositorySystem repositorySystem, MetadataRe
7888 public PluginPrefixResult resolve (PluginPrefixRequest request ) throws NoPluginFoundForPrefixException {
7989 logger .debug ("Resolving plugin prefix {} from {}" , request .getPrefix (), request .getPluginGroups ());
8090
91+ Model pom = request .getPom ();
92+ Build build = pom != null ? pom .getBuild () : null ;
93+ PluginManagement management = build != null ? build .getPluginManagement () : null ;
94+
8195 // map of groupId -> Set(artifactId) plugin candidates:
8296 // if value is null, keys are coming from settings, and no artifactId filtering is applied
8397 // if value is non-null: we allow only plugins that have enlisted artifactId only
8498 // ---
8599 // end game is: settings enlisted groupIds are obeying order and are "free for all" (artifactId)
86100 // while POM enlisted plugins coming from non-enlisted settings groupIds (ie conflict of prefixes)
87101 // will prevail/win.
88- LinkedHashMap <String , Set <String >> candidates = new LinkedHashMap <>();
89- if (request .getPom () != null ) {
90- if (request .getPom ().getBuild () != null ) {
91- request .getPom ().getBuild ().getPlugins ().stream ()
92- .filter (p -> !request .getPluginGroups ().contains (p .getGroupId ()))
93- .forEach (p -> candidates
94- .computeIfAbsent (p .getGroupId (), g -> new HashSet <>())
95- .add (p .getArtifactId ()));
96- if (request .getPom ().getBuild ().getPluginManagement () != null ) {
97- request .getPom ().getBuild ().getPluginManagement ().getPlugins ().stream ()
98- .filter (p -> !request .getPluginGroups ().contains (p .getGroupId ()))
99- .forEach (p -> candidates
100- .computeIfAbsent (p .getGroupId (), g -> new HashSet <>())
101- .add (p .getArtifactId ()));
102- }
103- }
104- }
102+ LinkedHashMap <String , Set <String >> candidates = Stream .of (build , management )
103+ .flatMap (container -> container != null ? container .getPlugins ().stream () : Stream .empty ())
104+ .filter (p -> !request .getPluginGroups ().contains (p .getGroupId ()))
105+ .collect (Collectors .groupingBy (
106+ Plugin ::getGroupId ,
107+ LinkedHashMap ::new ,
108+ Collectors .mapping (Plugin ::getArtifactId , Collectors .toSet ())));
105109 request .getPluginGroups ().forEach (g -> candidates .put (g , null ));
106110 PluginPrefixResult result = resolveFromRepository (request , candidates );
107111
112+ // If we haven't been able to resolve the plugin from the repository,
113+ // as a last resort, we go through all declared plugins, load them
114+ // one by one, and try to find a matching prefix.
115+ if (result == null && build != null ) {
116+ result = resolveFromProject (request , build .getPlugins ());
117+ if (result == null && management != null ) {
118+ result = resolveFromProject (request , management .getPlugins ());
119+ }
120+ }
121+
108122 if (result == null ) {
109123 throw new NoPluginFoundForPrefixException (
110124 request .getPrefix (),
@@ -123,6 +137,27 @@ public PluginPrefixResult resolve(PluginPrefixRequest request) throws NoPluginFo
123137 return result ;
124138 }
125139
140+ private PluginPrefixResult resolveFromProject (PluginPrefixRequest request , List <Plugin > plugins ) {
141+ for (Plugin plugin : plugins ) {
142+ try {
143+ PluginDescriptor pluginDescriptor =
144+ pluginManager .loadPlugin (plugin , request .getRepositories (), request .getRepositorySession ());
145+
146+ if (request .getPrefix ().equals (pluginDescriptor .getGoalPrefix ())) {
147+ return new DefaultPluginPrefixResult (plugin );
148+ }
149+ } catch (Exception e ) {
150+ if (logger .isDebugEnabled ()) {
151+ logger .warn ("Failed to retrieve plugin descriptor for {}: {}" , plugin .getId (), e .getMessage (), e );
152+ } else {
153+ logger .warn ("Failed to retrieve plugin descriptor for {}: {}" , plugin .getId (), e .getMessage ());
154+ }
155+ }
156+ }
157+
158+ return null ;
159+ }
160+
126161 private PluginPrefixResult resolveFromRepository (
127162 PluginPrefixRequest request , LinkedHashMap <String , Set <String >> candidates ) {
128163 RequestTrace trace = RequestTrace .newChild (null , request );
0 commit comments