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