1 package org.apache.maven.archetype.source;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.util.List;
25 import java.util.Map;
26
27 import org.apache.maven.archetype.catalog.Archetype;
28 import org.apache.maven.archetype.catalog.ArchetypeCatalog;
29 import org.apache.maven.artifact.repository.ArtifactRepository;
30 import org.apache.maven.execution.MavenExecutionRequest;
31 import org.apache.maven.execution.MavenSession;
32 import org.apache.maven.plugin.LegacySupport;
33 import org.apache.maven.project.ProjectBuildingRequest;
34 import org.apache.maven.settings.Mirror;
35 import org.apache.maven.settings.Proxy;
36 import org.apache.maven.settings.Server;
37 import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest;
38 import org.apache.maven.settings.crypto.SettingsDecrypter;
39 import org.apache.maven.settings.crypto.SettingsDecryptionResult;
40 import org.apache.maven.wagon.UnsupportedProtocolException;
41 import org.apache.maven.wagon.Wagon;
42 import org.apache.maven.wagon.WagonException;
43 import org.apache.maven.wagon.authentication.AuthenticationInfo;
44 import org.apache.maven.wagon.proxy.ProxyInfo;
45 import org.apache.maven.wagon.repository.Repository;
46 import org.codehaus.plexus.component.annotations.Component;
47 import org.codehaus.plexus.component.annotations.Requirement;
48 import org.codehaus.plexus.util.ReaderFactory;
49 import org.codehaus.plexus.util.StringUtils;
50
51
52
53
54 @Component( role = ArchetypeDataSource.class, hint = "remote-catalog" )
55 public class RemoteCatalogArchetypeDataSource extends CatalogArchetypeDataSource implements ArchetypeDataSource
56 {
57 @Requirement
58 private Map<String, Wagon> wagons;
59
60 @Requirement
61 private LegacySupport legacySupport;
62
63 @Requirement
64 private SettingsDecrypter settingsDecrypter;
65
66
67
68
69
70
71
72
73
74
75 public static final String ARCHETYPE_REPOSITORY_ID = "archetype";
76
77 public static final String CENTRAL_REPOSITORY_ID = "central";
78
79 @Override
80 public ArchetypeCatalog getArchetypeCatalog( ProjectBuildingRequest buildingRequest )
81 throws ArchetypeDataSourceException
82 {
83
84
85 final String archetypeRepoId;
86 Mirror archetypeMirror = getMirror( ARCHETYPE_REPOSITORY_ID );
87 if ( archetypeMirror != null )
88 {
89 archetypeRepoId = archetypeMirror.getId();
90 }
91 else
92 {
93 archetypeRepoId = ARCHETYPE_REPOSITORY_ID;
94 }
95
96 final String centralRepoId;
97 Mirror centralMirror = getMirror( CENTRAL_REPOSITORY_ID );
98 if ( centralMirror != null )
99 {
100 centralRepoId = centralMirror.getId();
101 }
102 else
103 {
104 centralRepoId = CENTRAL_REPOSITORY_ID;
105 }
106
107 ArtifactRepository centralRepository = null;
108 ArtifactRepository archetypeRepository = null;
109 for ( ArtifactRepository remoteRepository : buildingRequest.getRemoteRepositories() )
110 {
111 if ( archetypeRepoId.equals( remoteRepository.getId() ) )
112 {
113 archetypeRepository = remoteRepository;
114 break;
115 }
116 else if ( centralRepoId.equals( remoteRepository.getId() ) )
117 {
118 centralRepository = remoteRepository;
119 }
120 }
121
122 if ( archetypeRepository == null )
123 {
124 archetypeRepository = centralRepository;
125 }
126
127 try
128 {
129 return downloadCatalog( archetypeRepository );
130 }
131 catch ( IOException e )
132 {
133 throw new ArchetypeDataSourceException( e );
134 }
135 catch ( WagonException e )
136 {
137 throw new ArchetypeDataSourceException( e );
138 }
139 }
140
141 @Override
142 public void updateCatalog( ProjectBuildingRequest buildingRequest, Archetype archetype )
143 throws ArchetypeDataSourceException
144 {
145 throw new ArchetypeDataSourceException( "Not supported yet." );
146 }
147
148 private ArchetypeCatalog downloadCatalog( ArtifactRepository repository )
149 throws WagonException, IOException, ArchetypeDataSourceException
150 {
151 getLogger().debug( "Searching for remote catalog: " + repository.getUrl() + "/" + ARCHETYPE_CATALOG_FILENAME );
152
153
154 Repository wagonRepository = new Repository( repository.getId(), repository.getUrl() );
155
156 AuthenticationInfo authInfo = getAuthenticationInfo( wagonRepository.getId() );
157 ProxyInfo proxyInfo = getProxy( wagonRepository.getProtocol() );
158
159 Wagon wagon = getWagon( wagonRepository );
160
161 File catalog = File.createTempFile( "archetype-catalog", ".xml" );
162 try
163 {
164 wagon.connect( wagonRepository, authInfo, proxyInfo );
165 wagon.get( ARCHETYPE_CATALOG_FILENAME, catalog );
166
167 return readCatalog( ReaderFactory.newXmlReader( catalog ) );
168 }
169 finally
170 {
171 disconnectWagon( wagon );
172 catalog.delete();
173 }
174 }
175
176 private void disconnectWagon( Wagon wagon )
177 {
178 try
179 {
180 wagon.disconnect();
181 }
182 catch ( Exception e )
183 {
184 getLogger().warn( "Problem disconnecting from wagon - ignoring: " + e.getMessage() );
185 }
186 }
187
188
189
190 private Wagon getWagon( Repository repository )
191 throws UnsupportedProtocolException
192 {
193 return getWagon( repository.getProtocol() );
194 }
195
196 private Wagon getWagon( String protocol )
197 throws UnsupportedProtocolException
198 {
199 if ( protocol == null )
200 {
201 throw new UnsupportedProtocolException( "Unspecified protocol" );
202 }
203
204 String hint = protocol.toLowerCase( java.util.Locale.ENGLISH );
205
206 Wagon wagon = wagons.get( hint );
207 if ( wagon == null )
208 {
209 throw new UnsupportedProtocolException( "Cannot find wagon which supports the requested protocol: "
210 + protocol );
211 }
212
213 return wagon;
214 }
215
216 private AuthenticationInfo getAuthenticationInfo( String id )
217 {
218 MavenSession session = legacySupport.getSession();
219
220 if ( session != null && id != null )
221 {
222 MavenExecutionRequest request = session.getRequest();
223
224 if ( request != null )
225 {
226 List<Server> servers = request.getServers();
227
228 if ( servers != null )
229 {
230 for ( Server server : servers )
231 {
232 if ( id.equalsIgnoreCase( server.getId() ) )
233 {
234 SettingsDecryptionResult result =
235 settingsDecrypter.decrypt( new DefaultSettingsDecryptionRequest( server ) );
236 server = result.getServer();
237
238 AuthenticationInfo authInfo = new AuthenticationInfo();
239 authInfo.setUserName( server.getUsername() );
240 authInfo.setPassword( server.getPassword() );
241 authInfo.setPrivateKey( server.getPrivateKey() );
242 authInfo.setPassphrase( server.getPassphrase() );
243
244 return authInfo;
245 }
246 }
247 }
248 }
249 }
250
251
252 return new AuthenticationInfo();
253 }
254
255 private ProxyInfo getProxy( String protocol )
256 {
257 MavenSession session = legacySupport.getSession();
258
259 if ( session != null && protocol != null )
260 {
261 MavenExecutionRequest request = session.getRequest();
262
263 if ( request != null )
264 {
265 List<Proxy> proxies = request.getProxies();
266
267 if ( proxies != null )
268 {
269 for ( Proxy proxy : proxies )
270 {
271 if ( proxy.isActive() && protocol.equalsIgnoreCase( proxy.getProtocol() ) )
272 {
273 SettingsDecryptionResult result =
274 settingsDecrypter.decrypt( new DefaultSettingsDecryptionRequest( proxy ) );
275 proxy = result.getProxy();
276
277 ProxyInfo proxyInfo = new ProxyInfo();
278 proxyInfo.setHost( proxy.getHost() );
279 proxyInfo.setType( proxy.getProtocol() );
280 proxyInfo.setPort( proxy.getPort() );
281 proxyInfo.setNonProxyHosts( proxy.getNonProxyHosts() );
282 proxyInfo.setUserName( proxy.getUsername() );
283 proxyInfo.setPassword( proxy.getPassword() );
284
285 return proxyInfo;
286 }
287 }
288 }
289 }
290 }
291
292 return null;
293 }
294
295 private Mirror getMirror( String repoId )
296 {
297 MavenSession session = legacySupport.getSession();
298
299 MavenExecutionRequest request = null;
300
301 if ( session != null )
302 {
303 request = session.getRequest();
304 }
305
306 if ( request != null )
307 {
308 return getMirror( repoId, request.getMirrors() );
309 }
310
311 return null;
312 }
313
314 private static final String WILDCARD = "*";
315
316 private static final String EXTERNAL_WILDCARD = "external:*";
317
318 private Mirror getMirror( String repoId, List<Mirror> mirrors )
319 {
320 if ( repoId != null && mirrors != null )
321 {
322 for ( Mirror mirror : mirrors )
323 {
324 if ( repoId.equals( mirror.getMirrorOf() ) )
325 {
326 return mirror;
327 }
328 }
329
330 for ( Mirror mirror : mirrors )
331 {
332 if ( matchPattern( repoId, mirror.getMirrorOf() ) )
333 {
334 return mirror;
335 }
336 }
337 }
338
339 return null;
340 }
341
342
343
344
345
346
347
348
349
350
351 static boolean matchPattern( String originalId, String pattern )
352 {
353 boolean result = false;
354
355
356 if ( WILDCARD.equals( pattern ) || pattern.equals( originalId ) )
357 {
358 result = true;
359 }
360 else
361 {
362
363 String[] repos = pattern.split( "," );
364 for ( String repo : repos )
365 {
366
367 if ( repo.length() > 1 && repo.startsWith( "!" ) )
368 {
369 if ( repo.substring( 1 ).equals( originalId ) )
370 {
371
372 result = false;
373 break;
374 }
375 }
376
377 else if ( repo.equals( originalId ) )
378 {
379 result = true;
380 break;
381 }
382
383 else if ( EXTERNAL_WILDCARD.equals( repo ) )
384 {
385 result = true;
386
387 }
388 else if ( WILDCARD.equals( repo ) )
389 {
390 result = true;
391
392 }
393 }
394 }
395 return result;
396 }
397
398
399
400 static boolean matchesLayout( ArtifactRepository repository, Mirror mirror )
401 {
402 return matchesLayout( repository.getLayout().getId(), mirror.getMirrorOfLayouts() );
403 }
404
405
406
407
408
409
410
411
412
413 static boolean matchesLayout( String repoLayout, String mirrorLayout )
414 {
415 boolean result = false;
416
417
418 if ( StringUtils.isEmpty( mirrorLayout ) || WILDCARD.equals( mirrorLayout ) )
419 {
420 result = true;
421 }
422 else if ( mirrorLayout.equals( repoLayout ) )
423 {
424 result = true;
425 }
426 else
427 {
428
429 String[] layouts = mirrorLayout.split( "," );
430 for ( String layout : layouts )
431 {
432
433 if ( layout.length() > 1 && layout.startsWith( "!" ) )
434 {
435 if ( layout.substring( 1 ).equals( repoLayout ) )
436 {
437
438 result = false;
439 break;
440 }
441 }
442
443 else if ( layout.equals( repoLayout ) )
444 {
445 result = true;
446 break;
447 }
448 else if ( WILDCARD.equals( layout ) )
449 {
450 result = true;
451
452 }
453 }
454 }
455
456 return result;
457 }
458 }