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