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