1 package org.apache.maven.plugin.prefix.internal;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.List;
26 import java.util.Map;
27
28 import org.apache.maven.artifact.repository.metadata.Metadata;
29 import org.apache.maven.artifact.repository.metadata.io.MetadataReader;
30 import org.apache.maven.model.Build;
31 import org.apache.maven.model.Plugin;
32 import org.apache.maven.plugin.BuildPluginManager;
33 import org.apache.maven.plugin.descriptor.PluginDescriptor;
34 import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
35 import org.apache.maven.plugin.prefix.PluginPrefixRequest;
36 import org.apache.maven.plugin.prefix.PluginPrefixResolver;
37 import org.apache.maven.plugin.prefix.PluginPrefixResult;
38 import org.codehaus.plexus.component.annotations.Component;
39 import org.codehaus.plexus.component.annotations.Requirement;
40 import org.codehaus.plexus.logging.Logger;
41 import org.eclipse.aether.RepositoryEvent.EventType;
42 import org.eclipse.aether.DefaultRepositorySystemSession;
43 import org.eclipse.aether.RepositoryEvent;
44 import org.eclipse.aether.RepositoryListener;
45 import org.eclipse.aether.RepositorySystem;
46 import org.eclipse.aether.RepositorySystemSession;
47 import org.eclipse.aether.RequestTrace;
48 import org.eclipse.aether.metadata.DefaultMetadata;
49 import org.eclipse.aether.repository.ArtifactRepository;
50 import org.eclipse.aether.repository.RemoteRepository;
51 import org.eclipse.aether.repository.RepositoryPolicy;
52 import org.eclipse.aether.resolution.MetadataRequest;
53 import org.eclipse.aether.resolution.MetadataResult;
54
55
56
57
58
59
60
61 @Component( role = PluginPrefixResolver.class )
62 public class DefaultPluginPrefixResolver
63 implements PluginPrefixResolver
64 {
65
66 private static final String REPOSITORY_CONTEXT = "plugin";
67
68 @Requirement
69 private Logger logger;
70
71 @Requirement
72 private BuildPluginManager pluginManager;
73
74 @Requirement
75 private RepositorySystem repositorySystem;
76
77 @Requirement
78 private MetadataReader metadataReader;
79
80 public PluginPrefixResult resolve( PluginPrefixRequest request )
81 throws NoPluginFoundForPrefixException
82 {
83 logger.debug( "Resolving plugin prefix " + request.getPrefix() + " from " + request.getPluginGroups() );
84
85 PluginPrefixResult result = resolveFromProject( request );
86
87 if ( result == null )
88 {
89 result = resolveFromRepository( request );
90
91 if ( result == null )
92 {
93 throw new NoPluginFoundForPrefixException( request.getPrefix(), request.getPluginGroups(),
94 request.getRepositorySession().getLocalRepository(),
95 request.getRepositories() );
96 }
97 else if ( logger.isDebugEnabled() )
98 {
99 logger.debug( "Resolved plugin prefix " + request.getPrefix() + " to " + result.getGroupId() + ":"
100 + result.getArtifactId() + " from repository "
101 + ( result.getRepository() != null ? result.getRepository().getId() : "null" ) );
102 }
103 }
104 else if ( logger.isDebugEnabled() )
105 {
106 logger.debug( "Resolved plugin prefix " + request.getPrefix() + " to " + result.getGroupId() + ":"
107 + result.getArtifactId() + " from POM " + request.getPom() );
108 }
109
110 return result;
111 }
112
113 private PluginPrefixResult resolveFromProject( PluginPrefixRequest request )
114 {
115 PluginPrefixResult result = null;
116
117 if ( request.getPom() != null && request.getPom().getBuild() != null )
118 {
119 Build build = request.getPom().getBuild();
120
121 result = resolveFromProject( request, build.getPlugins() );
122
123 if ( result == null && build.getPluginManagement() != null )
124 {
125 result = resolveFromProject( request, build.getPluginManagement().getPlugins() );
126 }
127 }
128
129 return result;
130 }
131
132 private PluginPrefixResult resolveFromProject( PluginPrefixRequest request, List<Plugin> plugins )
133 {
134 for ( Plugin plugin : plugins )
135 {
136 try
137 {
138 PluginDescriptor pluginDescriptor =
139 pluginManager.loadPlugin( plugin, request.getRepositories(), request.getRepositorySession() );
140
141 if ( request.getPrefix().equals( pluginDescriptor.getGoalPrefix() ) )
142 {
143 return new DefaultPluginPrefixResult( plugin );
144 }
145 }
146 catch ( Exception e )
147 {
148 if ( logger.isDebugEnabled() )
149 {
150 logger.warn( "Failed to retrieve plugin descriptor for " + plugin.getId() + ": " + e.getMessage(),
151 e );
152 }
153 else
154 {
155 logger.warn( "Failed to retrieve plugin descriptor for " + plugin.getId() + ": " + e.getMessage() );
156 }
157 }
158 }
159
160 return null;
161 }
162
163 private PluginPrefixResult resolveFromRepository( PluginPrefixRequest request )
164 {
165 RequestTrace trace = RequestTrace.newChild( null, request );
166
167 List<MetadataRequest> requests = new ArrayList<>();
168
169 for ( String pluginGroup : request.getPluginGroups() )
170 {
171 org.eclipse.aether.metadata.Metadata metadata =
172 new DefaultMetadata( pluginGroup, "maven-metadata.xml", DefaultMetadata.Nature.RELEASE_OR_SNAPSHOT );
173
174 requests.add( new MetadataRequest( metadata, null, REPOSITORY_CONTEXT ).setTrace( trace ) );
175
176 for ( RemoteRepository repository : request.getRepositories() )
177 {
178 requests.add( new MetadataRequest( metadata, repository, REPOSITORY_CONTEXT ).setTrace( trace ) );
179 }
180 }
181
182
183
184 List<MetadataResult> results = repositorySystem.resolveMetadata( request.getRepositorySession(), requests );
185 requests.clear();
186
187 PluginPrefixResult result = processResults( request, trace, results, requests );
188
189 if ( result != null )
190 {
191 return result;
192 }
193
194
195
196 if ( !request.getRepositorySession().isOffline() && !requests.isEmpty() )
197 {
198 DefaultRepositorySystemSession session =
199 new DefaultRepositorySystemSession( request.getRepositorySession() );
200 session.setUpdatePolicy( RepositoryPolicy.UPDATE_POLICY_ALWAYS );
201
202 results = repositorySystem.resolveMetadata( session, requests );
203
204 return processResults( request, trace, results, null );
205 }
206
207 return null;
208 }
209
210 private PluginPrefixResult processResults( PluginPrefixRequest request, RequestTrace trace,
211 List<MetadataResult> results, List<MetadataRequest> requests )
212 {
213 for ( MetadataResult res : results )
214 {
215 org.eclipse.aether.metadata.Metadata metadata = res.getMetadata();
216
217 if ( metadata != null )
218 {
219 ArtifactRepository repository = res.getRequest().getRepository();
220 if ( repository == null )
221 {
222 repository = request.getRepositorySession().getLocalRepository();
223 }
224
225 PluginPrefixResult result =
226 resolveFromRepository( request, trace, metadata.getGroupId(), metadata, repository );
227
228 if ( result != null )
229 {
230 return result;
231 }
232 }
233
234 if ( requests != null && !res.isUpdated() )
235 {
236 requests.add( res.getRequest() );
237 }
238 }
239
240 return null;
241 }
242
243 private PluginPrefixResult resolveFromRepository( PluginPrefixRequest request, RequestTrace trace,
244 String pluginGroup,
245 org.eclipse.aether.metadata.Metadata metadata,
246 ArtifactRepository repository )
247 {
248 if ( metadata != null && metadata.getFile() != null && metadata.getFile().isFile() )
249 {
250 try
251 {
252 Map<String, ?> options = Collections.singletonMap( MetadataReader.IS_STRICT, Boolean.FALSE );
253
254 Metadata pluginGroupMetadata = metadataReader.read( metadata.getFile(), options );
255
256 List<org.apache.maven.artifact.repository.metadata.Plugin> plugins = pluginGroupMetadata.getPlugins();
257
258 if ( plugins != null )
259 {
260 for ( org.apache.maven.artifact.repository.metadata.Plugin plugin : plugins )
261 {
262 if ( request.getPrefix().equals( plugin.getPrefix() ) )
263 {
264 return new DefaultPluginPrefixResult( pluginGroup, plugin.getArtifactId(), repository );
265 }
266 }
267 }
268 }
269 catch ( IOException e )
270 {
271 invalidMetadata( request.getRepositorySession(), trace, metadata, repository, e );
272 }
273 }
274
275 return null;
276 }
277
278 private void invalidMetadata( RepositorySystemSession session, RequestTrace trace,
279 org.eclipse.aether.metadata.Metadata metadata, ArtifactRepository repository,
280 Exception exception )
281 {
282 RepositoryListener listener = session.getRepositoryListener();
283 if ( listener != null )
284 {
285 RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.METADATA_INVALID );
286 event.setTrace( trace );
287 event.setMetadata( metadata );
288 event.setException( exception );
289 event.setRepository( repository );
290 listener.metadataInvalid( event.build() );
291 }
292 }
293
294 }