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.WorkspaceRepository;
56 import org.eclipse.aether.resolution.ArtifactDescriptorException;
57 import org.eclipse.aether.resolution.ArtifactDescriptorPolicy;
58 import org.eclipse.aether.resolution.ArtifactDescriptorPolicyRequest;
59 import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
60 import org.eclipse.aether.resolution.ArtifactDescriptorResult;
61 import org.eclipse.aether.resolution.ArtifactRequest;
62 import org.eclipse.aether.resolution.ArtifactResolutionException;
63 import org.eclipse.aether.resolution.ArtifactResult;
64 import org.eclipse.aether.resolution.VersionRequest;
65 import org.eclipse.aether.resolution.VersionResolutionException;
66 import org.eclipse.aether.resolution.VersionResult;
67 import org.eclipse.aether.spi.locator.Service;
68 import org.eclipse.aether.spi.locator.ServiceLocator;
69 import org.eclipse.aether.spi.log.Logger;
70 import org.eclipse.aether.spi.log.LoggerFactory;
71 import org.eclipse.aether.spi.log.NullLoggerFactory;
72 import org.eclipse.aether.transfer.ArtifactNotFoundException;
73
74
75
76
77 @Named
78 @Component( role = ArtifactDescriptorReader.class )
79 public class DefaultArtifactDescriptorReader
80 implements ArtifactDescriptorReader, Service
81 {
82
83 @SuppressWarnings( "unused" )
84 @Requirement( role = LoggerFactory.class )
85 private Logger logger = NullLoggerFactory.LOGGER;
86
87 @Requirement
88 private RemoteRepositoryManager remoteRepositoryManager;
89
90 @Requirement
91 private VersionResolver versionResolver;
92
93 @Requirement
94 private VersionRangeResolver versionRangeResolver;
95
96 @Requirement
97 private ArtifactResolver artifactResolver;
98
99 @Requirement
100 private RepositoryEventDispatcher repositoryEventDispatcher;
101
102 @Requirement
103 private ModelBuilder modelBuilder;
104
105 public DefaultArtifactDescriptorReader()
106 {
107
108 }
109
110 @Inject
111 DefaultArtifactDescriptorReader( RemoteRepositoryManager remoteRepositoryManager, VersionResolver versionResolver,
112 ArtifactResolver artifactResolver, ModelBuilder modelBuilder,
113 RepositoryEventDispatcher repositoryEventDispatcher, LoggerFactory loggerFactory )
114 {
115 setRemoteRepositoryManager( remoteRepositoryManager );
116 setVersionResolver( versionResolver );
117 setArtifactResolver( artifactResolver );
118 setModelBuilder( modelBuilder );
119 setLoggerFactory( loggerFactory );
120 setRepositoryEventDispatcher( repositoryEventDispatcher );
121 }
122
123 public void initService( ServiceLocator locator )
124 {
125 setLoggerFactory( locator.getService( LoggerFactory.class ) );
126 setRemoteRepositoryManager( locator.getService( RemoteRepositoryManager.class ) );
127 setVersionResolver( locator.getService( VersionResolver.class ) );
128 setVersionRangeResolver( locator.getService( VersionRangeResolver.class ) );
129 setArtifactResolver( locator.getService( ArtifactResolver.class ) );
130 setRepositoryEventDispatcher( locator.getService( RepositoryEventDispatcher.class ) );
131 modelBuilder = locator.getService( ModelBuilder.class );
132 if ( modelBuilder == null )
133 {
134 setModelBuilder( new DefaultModelBuilderFactory().newInstance() );
135 }
136 }
137
138 public DefaultArtifactDescriptorReader setLoggerFactory( LoggerFactory loggerFactory )
139 {
140 this.logger = NullLoggerFactory.getSafeLogger( loggerFactory, getClass() );
141 return this;
142 }
143
144 void setLogger( LoggerFactory loggerFactory )
145 {
146
147 setLoggerFactory( loggerFactory );
148 }
149
150 public DefaultArtifactDescriptorReader setRemoteRepositoryManager( RemoteRepositoryManager remoteRepositoryManager )
151 {
152 if ( remoteRepositoryManager == null )
153 {
154 throw new IllegalArgumentException( "remote repository manager has not been specified" );
155 }
156 this.remoteRepositoryManager = remoteRepositoryManager;
157 return this;
158 }
159
160 public DefaultArtifactDescriptorReader setVersionResolver( VersionResolver versionResolver )
161 {
162 if ( versionResolver == null )
163 {
164 throw new IllegalArgumentException( "version resolver has not been specified" );
165 }
166 this.versionResolver = versionResolver;
167 return this;
168 }
169
170
171 public DefaultArtifactDescriptorReader setVersionRangeResolver( VersionRangeResolver versionRangeResolver )
172 {
173 if ( versionRangeResolver == null )
174 {
175 throw new IllegalArgumentException( "version range resolver has not been specified" );
176 }
177 this.versionRangeResolver = versionRangeResolver;
178 return this;
179 }
180
181 public DefaultArtifactDescriptorReader setArtifactResolver( ArtifactResolver artifactResolver )
182 {
183 if ( artifactResolver == null )
184 {
185 throw new IllegalArgumentException( "artifact resolver has not been specified" );
186 }
187 this.artifactResolver = artifactResolver;
188 return this;
189 }
190
191 public DefaultArtifactDescriptorReader setRepositoryEventDispatcher( RepositoryEventDispatcher red )
192 {
193 if ( red == null )
194 {
195 throw new IllegalArgumentException( "repository event dispatcher has not been specified" );
196 }
197 this.repositoryEventDispatcher = red;
198 return this;
199 }
200
201 public DefaultArtifactDescriptorReader setModelBuilder( ModelBuilder modelBuilder )
202 {
203 if ( modelBuilder == null )
204 {
205 throw new IllegalArgumentException( "model builder has not been specified" );
206 }
207 this.modelBuilder = modelBuilder;
208 return this;
209 }
210
211 public ArtifactDescriptorResult readArtifactDescriptor( RepositorySystemSession session,
212 ArtifactDescriptorRequest request )
213 throws ArtifactDescriptorException
214 {
215 ArtifactDescriptorResult result = new ArtifactDescriptorResult( request );
216
217 Model model = loadPom( session, request, result );
218
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 try
307 {
308 ModelBuildingRequest modelRequest = new DefaultModelBuildingRequest();
309 modelRequest.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL );
310 modelRequest.setProcessPlugins( false );
311 modelRequest.setTwoPhaseBuilding( false );
312 modelRequest.setSystemProperties( toProperties( session.getUserProperties(),
313 session.getSystemProperties() ) );
314 modelRequest.setModelCache( DefaultModelCache.newInstance( session ) );
315 modelRequest.setModelResolver( new DefaultModelResolver( session, trace.newChild( modelRequest ),
316 request.getRequestContext(), artifactResolver,
317 versionRangeResolver, remoteRepositoryManager,
318 request.getRepositories() ) );
319 if ( resolveResult.getRepository() instanceof WorkspaceRepository )
320 {
321 modelRequest.setPomFile( pomArtifact.getFile() );
322 }
323 else
324 {
325 modelRequest.setModelSource( new FileModelSource( pomArtifact.getFile() ) );
326 }
327
328 model = modelBuilder.build( modelRequest ).getEffectiveModel();
329 }
330 catch ( ModelBuildingException e )
331 {
332 for ( ModelProblem problem : e.getProblems() )
333 {
334 if ( problem.getException() instanceof UnresolvableModelException )
335 {
336 result.addException( problem.getException() );
337 throw new ArtifactDescriptorException( result );
338 }
339 }
340 invalidDescriptor( session, trace, a, e );
341 if ( ( getPolicy( session, a, request ) & ArtifactDescriptorPolicy.IGNORE_INVALID ) != 0 )
342 {
343 return null;
344 }
345 result.addException( e );
346 throw new ArtifactDescriptorException( result );
347 }
348
349 Relocation relocation = getRelocation( model );
350
351 if ( relocation != null )
352 {
353 result.addRelocation( a );
354 a =
355 new RelocatedArtifact( a, relocation.getGroupId(), relocation.getArtifactId(),
356 relocation.getVersion() );
357 result.setArtifact( a );
358 }
359 else
360 {
361 return model;
362 }
363 }
364 }
365
366 private Properties toProperties( Map<String, String> dominant, Map<String, String> recessive )
367 {
368 Properties props = new Properties();
369 if ( recessive != null )
370 {
371 props.putAll( recessive );
372 }
373 if ( dominant != null )
374 {
375 props.putAll( dominant );
376 }
377 return props;
378 }
379
380 private Relocation getRelocation( Model model )
381 {
382 Relocation relocation = null;
383 DistributionManagement distMngt = model.getDistributionManagement();
384 if ( distMngt != null )
385 {
386 relocation = distMngt.getRelocation();
387 }
388 return relocation;
389 }
390
391 private void missingDescriptor( RepositorySystemSession session, RequestTrace trace, Artifact artifact,
392 Exception exception )
393 {
394 RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.ARTIFACT_DESCRIPTOR_MISSING );
395 event.setTrace( trace );
396 event.setArtifact( artifact );
397 event.setException( exception );
398
399 repositoryEventDispatcher.dispatch( event.build() );
400 }
401
402 private void invalidDescriptor( RepositorySystemSession session, RequestTrace trace, Artifact artifact,
403 Exception exception )
404 {
405 RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.ARTIFACT_DESCRIPTOR_INVALID );
406 event.setTrace( trace );
407 event.setArtifact( artifact );
408 event.setException( exception );
409
410 repositoryEventDispatcher.dispatch( event.build() );
411 }
412
413 private int getPolicy( RepositorySystemSession session, Artifact a, ArtifactDescriptorRequest request )
414 {
415 ArtifactDescriptorPolicy policy = session.getArtifactDescriptorPolicy();
416 if ( policy == null )
417 {
418 return ArtifactDescriptorPolicy.STRICT;
419 }
420 return policy.getPolicy( session, new ArtifactDescriptorPolicyRequest( a, request.getRequestContext() ) );
421 }
422
423 }