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