1 package org.apache.maven.repository.internal;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.LinkedHashSet;
23 import java.util.Map;
24 import java.util.Properties;
25 import java.util.Set;
26
27 import javax.inject.Inject;
28 import javax.inject.Named;
29
30 import org.apache.maven.model.DistributionManagement;
31 import org.apache.maven.model.Model;
32 import org.apache.maven.model.Relocation;
33 import org.apache.maven.model.building.DefaultModelBuilderFactory;
34 import org.apache.maven.model.building.DefaultModelBuildingRequest;
35 import org.apache.maven.model.building.FileModelSource;
36 import org.apache.maven.model.building.ModelBuilder;
37 import org.apache.maven.model.building.ModelBuildingException;
38 import org.apache.maven.model.building.ModelBuildingRequest;
39 import org.apache.maven.model.building.ModelProblem;
40 import org.apache.maven.model.resolution.UnresolvableModelException;
41 import org.codehaus.plexus.component.annotations.Component;
42 import org.codehaus.plexus.component.annotations.Requirement;
43 import org.eclipse.aether.RepositoryEvent;
44 import org.eclipse.aether.RepositoryEvent.EventType;
45 import org.eclipse.aether.RepositoryException;
46 import org.eclipse.aether.RepositorySystemSession;
47 import org.eclipse.aether.RequestTrace;
48 import org.eclipse.aether.artifact.Artifact;
49 import org.eclipse.aether.impl.ArtifactDescriptorReader;
50 import org.eclipse.aether.impl.ArtifactResolver;
51 import org.eclipse.aether.impl.RemoteRepositoryManager;
52 import org.eclipse.aether.impl.RepositoryEventDispatcher;
53 import org.eclipse.aether.impl.VersionRangeResolver;
54 import org.eclipse.aether.impl.VersionResolver;
55 import org.eclipse.aether.repository.WorkspaceReader;
56 import org.eclipse.aether.repository.WorkspaceRepository;
57 import org.eclipse.aether.resolution.ArtifactDescriptorException;
58 import org.eclipse.aether.resolution.ArtifactDescriptorPolicy;
59 import org.eclipse.aether.resolution.ArtifactDescriptorPolicyRequest;
60 import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
61 import org.eclipse.aether.resolution.ArtifactDescriptorResult;
62 import org.eclipse.aether.resolution.ArtifactRequest;
63 import org.eclipse.aether.resolution.ArtifactResolutionException;
64 import org.eclipse.aether.resolution.ArtifactResult;
65 import org.eclipse.aether.resolution.VersionRequest;
66 import org.eclipse.aether.resolution.VersionResolutionException;
67 import org.eclipse.aether.resolution.VersionResult;
68 import org.eclipse.aether.spi.locator.Service;
69 import org.eclipse.aether.spi.locator.ServiceLocator;
70 import org.eclipse.aether.spi.log.Logger;
71 import org.eclipse.aether.spi.log.LoggerFactory;
72 import org.eclipse.aether.spi.log.NullLoggerFactory;
73 import org.eclipse.aether.transfer.ArtifactNotFoundException;
74
75
76
77
78 @Named
79 @Component( role = ArtifactDescriptorReader.class )
80 public class DefaultArtifactDescriptorReader
81 implements ArtifactDescriptorReader, Service
82 {
83
84 @SuppressWarnings( "unused" )
85 @Requirement( role = LoggerFactory.class )
86 private Logger logger = NullLoggerFactory.LOGGER;
87
88 @Requirement
89 private RemoteRepositoryManager remoteRepositoryManager;
90
91 @Requirement
92 private VersionResolver versionResolver;
93
94 @Requirement
95 private VersionRangeResolver versionRangeResolver;
96
97 @Requirement
98 private ArtifactResolver artifactResolver;
99
100 @Requirement
101 private RepositoryEventDispatcher repositoryEventDispatcher;
102
103 @Requirement
104 private ModelBuilder modelBuilder;
105
106 public DefaultArtifactDescriptorReader()
107 {
108
109 }
110
111 @Inject
112 DefaultArtifactDescriptorReader( RemoteRepositoryManager remoteRepositoryManager, VersionResolver versionResolver,
113 ArtifactResolver artifactResolver, ModelBuilder modelBuilder,
114 RepositoryEventDispatcher repositoryEventDispatcher, LoggerFactory loggerFactory )
115 {
116 setRemoteRepositoryManager( remoteRepositoryManager );
117 setVersionResolver( versionResolver );
118 setArtifactResolver( artifactResolver );
119 setModelBuilder( modelBuilder );
120 setLoggerFactory( loggerFactory );
121 setRepositoryEventDispatcher( repositoryEventDispatcher );
122 }
123
124 public void initService( ServiceLocator locator )
125 {
126 setLoggerFactory( locator.getService( LoggerFactory.class ) );
127 setRemoteRepositoryManager( locator.getService( RemoteRepositoryManager.class ) );
128 setVersionResolver( locator.getService( VersionResolver.class ) );
129 setVersionRangeResolver( locator.getService( VersionRangeResolver.class ) );
130 setArtifactResolver( locator.getService( ArtifactResolver.class ) );
131 setRepositoryEventDispatcher( locator.getService( RepositoryEventDispatcher.class ) );
132 modelBuilder = locator.getService( ModelBuilder.class );
133 if ( modelBuilder == null )
134 {
135 setModelBuilder( new DefaultModelBuilderFactory().newInstance() );
136 }
137 }
138
139 public DefaultArtifactDescriptorReader setLoggerFactory( LoggerFactory loggerFactory )
140 {
141 this.logger = NullLoggerFactory.getSafeLogger( loggerFactory, getClass() );
142 return this;
143 }
144
145 void setLogger( LoggerFactory loggerFactory )
146 {
147
148 setLoggerFactory( loggerFactory );
149 }
150
151 public DefaultArtifactDescriptorReader setRemoteRepositoryManager( RemoteRepositoryManager remoteRepositoryManager )
152 {
153 if ( remoteRepositoryManager == null )
154 {
155 throw new IllegalArgumentException( "remote repository manager has not been specified" );
156 }
157 this.remoteRepositoryManager = remoteRepositoryManager;
158 return this;
159 }
160
161 public DefaultArtifactDescriptorReader setVersionResolver( VersionResolver versionResolver )
162 {
163 if ( versionResolver == null )
164 {
165 throw new IllegalArgumentException( "version resolver has not been specified" );
166 }
167 this.versionResolver = versionResolver;
168 return this;
169 }
170
171
172 public DefaultArtifactDescriptorReader setVersionRangeResolver( VersionRangeResolver versionRangeResolver )
173 {
174 if ( versionRangeResolver == null )
175 {
176 throw new IllegalArgumentException( "version range resolver has not been specified" );
177 }
178 this.versionRangeResolver = versionRangeResolver;
179 return this;
180 }
181
182 public DefaultArtifactDescriptorReader setArtifactResolver( ArtifactResolver artifactResolver )
183 {
184 if ( artifactResolver == null )
185 {
186 throw new IllegalArgumentException( "artifact resolver has not been specified" );
187 }
188 this.artifactResolver = artifactResolver;
189 return this;
190 }
191
192 public DefaultArtifactDescriptorReader setRepositoryEventDispatcher( RepositoryEventDispatcher red )
193 {
194 if ( red == null )
195 {
196 throw new IllegalArgumentException( "repository event dispatcher has not been specified" );
197 }
198 this.repositoryEventDispatcher = red;
199 return this;
200 }
201
202 public DefaultArtifactDescriptorReader setModelBuilder( ModelBuilder modelBuilder )
203 {
204 if ( modelBuilder == null )
205 {
206 throw new IllegalArgumentException( "model builder has not been specified" );
207 }
208 this.modelBuilder = modelBuilder;
209 return this;
210 }
211
212 public ArtifactDescriptorResult readArtifactDescriptor( RepositorySystemSession session,
213 ArtifactDescriptorRequest request )
214 throws ArtifactDescriptorException
215 {
216 ArtifactDescriptorResult result = new ArtifactDescriptorResult( request );
217
218 Model model = loadPom( session, request, result );
219 if ( model != null )
220 {
221 Map<String, Object> config = session.getConfigProperties();
222 ArtifactDescriptorReaderDelegate delegate =
223 (ArtifactDescriptorReaderDelegate) config.get( ArtifactDescriptorReaderDelegate.class.getName() );
224
225 if ( delegate == null )
226 {
227 delegate = new ArtifactDescriptorReaderDelegate();
228 }
229
230 delegate.populateResult( session, result, model );
231 }
232
233 return result;
234 }
235
236 private Model loadPom( RepositorySystemSession session, ArtifactDescriptorRequest request,
237 ArtifactDescriptorResult result )
238 throws ArtifactDescriptorException
239 {
240 RequestTrace trace = RequestTrace.newChild( request.getTrace(), request );
241
242 Set<String> visited = new LinkedHashSet<String>();
243 for ( Artifact a = request.getArtifact();; )
244 {
245 Artifact pomArtifact = ArtifactDescriptorUtils.toPomArtifact( a );
246 try
247 {
248 VersionRequest versionRequest =
249 new VersionRequest( a, request.getRepositories(), request.getRequestContext() );
250 versionRequest.setTrace( trace );
251 VersionResult versionResult = versionResolver.resolveVersion( session, versionRequest );
252
253 a = a.setVersion( versionResult.getVersion() );
254
255 versionRequest =
256 new VersionRequest( pomArtifact, request.getRepositories(), request.getRequestContext() );
257 versionRequest.setTrace( trace );
258 versionResult = versionResolver.resolveVersion( session, versionRequest );
259
260 pomArtifact = pomArtifact.setVersion( versionResult.getVersion() );
261 }
262 catch ( VersionResolutionException e )
263 {
264 result.addException( e );
265 throw new ArtifactDescriptorException( result );
266 }
267
268 if ( !visited.add( a.getGroupId() + ':' + a.getArtifactId() + ':' + a.getBaseVersion() ) )
269 {
270 RepositoryException exception =
271 new RepositoryException( "Artifact relocations form a cycle: " + visited );
272 invalidDescriptor( session, trace, a, exception );
273 if ( ( getPolicy( session, a, request ) & ArtifactDescriptorPolicy.IGNORE_INVALID ) != 0 )
274 {
275 return null;
276 }
277 result.addException( exception );
278 throw new ArtifactDescriptorException( result );
279 }
280
281 ArtifactResult resolveResult;
282 try
283 {
284 ArtifactRequest resolveRequest =
285 new ArtifactRequest( pomArtifact, request.getRepositories(), request.getRequestContext() );
286 resolveRequest.setTrace( trace );
287 resolveResult = artifactResolver.resolveArtifact( session, resolveRequest );
288 pomArtifact = resolveResult.getArtifact();
289 result.setRepository( resolveResult.getRepository() );
290 }
291 catch ( ArtifactResolutionException e )
292 {
293 if ( e.getCause() instanceof ArtifactNotFoundException )
294 {
295 missingDescriptor( session, trace, a, (Exception) e.getCause() );
296 if ( ( getPolicy( session, a, request ) & ArtifactDescriptorPolicy.IGNORE_MISSING ) != 0 )
297 {
298 return null;
299 }
300 }
301 result.addException( e );
302 throw new ArtifactDescriptorException( result );
303 }
304
305 Model model;
306
307
308 final WorkspaceReader workspace = session.getWorkspaceReader();
309 if ( workspace instanceof MavenWorkspaceReader )
310 {
311 model = ( (MavenWorkspaceReader) workspace ).findModel( pomArtifact );
312 if ( model != null )
313 {
314 return model;
315 }
316 }
317
318 try
319 {
320 ModelBuildingRequest modelRequest = new DefaultModelBuildingRequest();
321 modelRequest.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL );
322 modelRequest.setProcessPlugins( false );
323 modelRequest.setTwoPhaseBuilding( false );
324 modelRequest.setSystemProperties( toProperties( session.getUserProperties(),
325 session.getSystemProperties() ) );
326 modelRequest.setModelCache( DefaultModelCache.newInstance( session ) );
327 modelRequest.setModelResolver( new DefaultModelResolver( session, trace.newChild( modelRequest ),
328 request.getRequestContext(), artifactResolver,
329 versionRangeResolver, remoteRepositoryManager,
330 request.getRepositories() ) );
331 if ( resolveResult.getRepository() instanceof WorkspaceRepository )
332 {
333 modelRequest.setPomFile( pomArtifact.getFile() );
334 }
335 else
336 {
337 modelRequest.setModelSource( new FileModelSource( pomArtifact.getFile() ) );
338 }
339
340 model = modelBuilder.build( modelRequest ).getEffectiveModel();
341 }
342 catch ( ModelBuildingException e )
343 {
344 for ( ModelProblem problem : e.getProblems() )
345 {
346 if ( problem.getException() instanceof UnresolvableModelException )
347 {
348 result.addException( problem.getException() );
349 throw new ArtifactDescriptorException( result );
350 }
351 }
352 invalidDescriptor( session, trace, a, e );
353 if ( ( getPolicy( session, a, request ) & ArtifactDescriptorPolicy.IGNORE_INVALID ) != 0 )
354 {
355 return null;
356 }
357 result.addException( e );
358 throw new ArtifactDescriptorException( result );
359 }
360
361 Relocation relocation = getRelocation( model );
362
363 if ( relocation != null )
364 {
365 result.addRelocation( a );
366 a =
367 new RelocatedArtifact( a, relocation.getGroupId(), relocation.getArtifactId(),
368 relocation.getVersion() );
369 result.setArtifact( a );
370 }
371 else
372 {
373 return model;
374 }
375 }
376 }
377
378 private Properties toProperties( Map<String, String> dominant, Map<String, String> recessive )
379 {
380 Properties props = new Properties();
381 if ( recessive != null )
382 {
383 props.putAll( recessive );
384 }
385 if ( dominant != null )
386 {
387 props.putAll( dominant );
388 }
389 return props;
390 }
391
392 private Relocation getRelocation( Model model )
393 {
394 Relocation relocation = null;
395 DistributionManagement distMngt = model.getDistributionManagement();
396 if ( distMngt != null )
397 {
398 relocation = distMngt.getRelocation();
399 }
400 return relocation;
401 }
402
403 private void missingDescriptor( RepositorySystemSession session, RequestTrace trace, Artifact artifact,
404 Exception exception )
405 {
406 RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.ARTIFACT_DESCRIPTOR_MISSING );
407 event.setTrace( trace );
408 event.setArtifact( artifact );
409 event.setException( exception );
410
411 repositoryEventDispatcher.dispatch( event.build() );
412 }
413
414 private void invalidDescriptor( RepositorySystemSession session, RequestTrace trace, Artifact artifact,
415 Exception exception )
416 {
417 RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.ARTIFACT_DESCRIPTOR_INVALID );
418 event.setTrace( trace );
419 event.setArtifact( artifact );
420 event.setException( exception );
421
422 repositoryEventDispatcher.dispatch( event.build() );
423 }
424
425 private int getPolicy( RepositorySystemSession session, Artifact a, ArtifactDescriptorRequest request )
426 {
427 ArtifactDescriptorPolicy policy = session.getArtifactDescriptorPolicy();
428 if ( policy == null )
429 {
430 return ArtifactDescriptorPolicy.STRICT;
431 }
432 return policy.getPolicy( session, new ArtifactDescriptorPolicyRequest( a, request.getRequestContext() ) );
433 }
434
435 }