1 package org.eclipse.aether.internal.impl.collect.df;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.Collections;
23 import java.util.List;
24
25 import javax.inject.Inject;
26 import javax.inject.Named;
27 import javax.inject.Singleton;
28
29 import org.eclipse.aether.RepositorySystemSession;
30 import org.eclipse.aether.RequestTrace;
31 import org.eclipse.aether.artifact.Artifact;
32 import org.eclipse.aether.collection.CollectRequest;
33 import org.eclipse.aether.collection.DependencyManager;
34 import org.eclipse.aether.collection.DependencySelector;
35 import org.eclipse.aether.collection.DependencyTraverser;
36 import org.eclipse.aether.collection.VersionFilter;
37 import org.eclipse.aether.graph.DefaultDependencyNode;
38 import org.eclipse.aether.graph.Dependency;
39 import org.eclipse.aether.graph.DependencyNode;
40 import org.eclipse.aether.impl.ArtifactDescriptorReader;
41 import org.eclipse.aether.impl.RemoteRepositoryManager;
42 import org.eclipse.aether.impl.VersionRangeResolver;
43 import org.eclipse.aether.internal.impl.collect.DataPool;
44 import org.eclipse.aether.internal.impl.collect.DefaultDependencyCollectionContext;
45 import org.eclipse.aether.internal.impl.collect.DefaultDependencyCycle;
46 import org.eclipse.aether.internal.impl.collect.DefaultVersionFilterContext;
47 import org.eclipse.aether.internal.impl.collect.DependencyCollectorDelegate;
48 import org.eclipse.aether.internal.impl.collect.PremanagedDependency;
49 import org.eclipse.aether.repository.RemoteRepository;
50 import org.eclipse.aether.resolution.ArtifactDescriptorException;
51 import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
52 import org.eclipse.aether.resolution.ArtifactDescriptorResult;
53 import org.eclipse.aether.resolution.VersionRangeRequest;
54 import org.eclipse.aether.resolution.VersionRangeResolutionException;
55 import org.eclipse.aether.resolution.VersionRangeResult;
56 import org.eclipse.aether.spi.locator.Service;
57 import org.eclipse.aether.util.ConfigUtils;
58 import org.eclipse.aether.util.graph.manager.DependencyManagerUtils;
59 import org.eclipse.aether.version.Version;
60
61
62
63
64
65
66
67 @Singleton
68 @Named( DfDependencyCollector.NAME )
69 public class DfDependencyCollector
70 extends DependencyCollectorDelegate implements Service
71 {
72 public static final String NAME = "df";
73
74
75
76
77
78
79 @Deprecated
80 public DfDependencyCollector()
81 {
82
83 }
84
85 @Inject
86 DfDependencyCollector( RemoteRepositoryManager remoteRepositoryManager,
87 ArtifactDescriptorReader artifactDescriptorReader,
88 VersionRangeResolver versionRangeResolver )
89 {
90 super( remoteRepositoryManager, artifactDescriptorReader, versionRangeResolver );
91 }
92
93 @SuppressWarnings( "checkstyle:parameternumber" )
94 @Override
95 protected void doCollectDependencies( RepositorySystemSession session, RequestTrace trace, DataPool pool,
96 DefaultDependencyCollectionContext context,
97 DefaultVersionFilterContext versionContext,
98 CollectRequest request, DependencyNode node,
99 List<RemoteRepository> repositories, List<Dependency> dependencies,
100 List<Dependency> managedDependencies, Results results )
101 {
102 NodeStack nodes = new NodeStack();
103 nodes.push( node );
104
105 Args args = new Args( session, pool, nodes, context, versionContext, request );
106
107 process( args, trace, results, dependencies, repositories,
108 session.getDependencySelector() != null
109 ? session.getDependencySelector().deriveChildSelector( context ) : null,
110 session.getDependencyManager() != null
111 ? session.getDependencyManager().deriveChildManager( context ) : null,
112 session.getDependencyTraverser() != null
113 ? session.getDependencyTraverser().deriveChildTraverser( context ) : null,
114 session.getVersionFilter() != null
115 ? session.getVersionFilter().deriveChildFilter( context ) : null );
116 }
117
118 @SuppressWarnings( "checkstyle:parameternumber" )
119 private void process( final Args args, RequestTrace trace, Results results, List<Dependency> dependencies,
120 List<RemoteRepository> repositories, DependencySelector depSelector,
121 DependencyManager depManager, DependencyTraverser depTraverser, VersionFilter verFilter )
122 {
123 for ( Dependency dependency : dependencies )
124 {
125 processDependency( args, trace, results, repositories, depSelector, depManager, depTraverser, verFilter,
126 dependency );
127 }
128 }
129
130 @SuppressWarnings( "checkstyle:parameternumber" )
131 private void processDependency( Args args, RequestTrace trace, Results results, List<RemoteRepository> repositories,
132 DependencySelector depSelector, DependencyManager depManager,
133 DependencyTraverser depTraverser, VersionFilter verFilter, Dependency dependency )
134 {
135
136 List<Artifact> relocations = Collections.emptyList();
137 processDependency( args, trace, results, repositories, depSelector, depManager, depTraverser, verFilter,
138 dependency, relocations, false );
139 }
140
141 @SuppressWarnings( "checkstyle:parameternumber" )
142 private void processDependency( Args args, RequestTrace parent, Results results,
143 List<RemoteRepository> repositories, DependencySelector depSelector,
144 DependencyManager depManager, DependencyTraverser depTraverser,
145 VersionFilter verFilter, Dependency dependency, List<Artifact> relocations,
146 boolean disableVersionManagement )
147 {
148 if ( depSelector != null && !depSelector.selectDependency( dependency ) )
149 {
150 return;
151 }
152
153 RequestTrace trace = collectStepTrace( parent, args.request.getRequestContext(), args.nodes.nodes, dependency );
154 PremanagedDependency preManaged =
155 PremanagedDependency.create( depManager, dependency, disableVersionManagement, args.premanagedState );
156 dependency = preManaged.getManagedDependency();
157
158 boolean noDescriptor = isLackingDescriptor( dependency.getArtifact() );
159
160 boolean traverse = !noDescriptor && ( depTraverser == null || depTraverser.traverseDependency( dependency ) );
161
162 List<? extends Version> versions;
163 VersionRangeResult rangeResult;
164 try
165 {
166 VersionRangeRequest rangeRequest = createVersionRangeRequest( args.request.getRequestContext(), trace,
167 repositories, dependency );
168
169 rangeResult = cachedResolveRangeResult( rangeRequest, args.pool, args.session );
170
171 versions = filterVersions( dependency, rangeResult, verFilter, args.versionContext );
172 }
173 catch ( VersionRangeResolutionException e )
174 {
175 results.addException( dependency, e, args.nodes.nodes );
176 return;
177 }
178
179 for ( Version version : versions )
180 {
181 Artifact originalArtifact = dependency.getArtifact().setVersion( version.toString() );
182 Dependency d = dependency.setArtifact( originalArtifact );
183
184 ArtifactDescriptorRequest descriptorRequest = createArtifactDescriptorRequest(
185 args.request.getRequestContext(), trace, repositories, d );
186
187 final ArtifactDescriptorResult descriptorResult =
188 getArtifactDescriptorResult( args, results, noDescriptor, d, descriptorRequest );
189 if ( descriptorResult != null )
190 {
191 d = d.setArtifact( descriptorResult.getArtifact() );
192
193 DependencyNode node = args.nodes.top();
194
195 int cycleEntry = DefaultDependencyCycle.find( args.nodes.nodes, d.getArtifact() );
196 if ( cycleEntry >= 0 )
197 {
198 results.addCycle( args.nodes.nodes, cycleEntry, d );
199 DependencyNode cycleNode = args.nodes.get( cycleEntry );
200 if ( cycleNode.getDependency() != null )
201 {
202 DefaultDependencyNode child =
203 createDependencyNode( relocations, preManaged, rangeResult, version, d, descriptorResult,
204 cycleNode );
205 node.getChildren().add( child );
206 continue;
207 }
208 }
209
210 if ( !descriptorResult.getRelocations().isEmpty() )
211 {
212 boolean disableVersionManagementSubsequently =
213 originalArtifact.getGroupId().equals( d.getArtifact().getGroupId() )
214 && originalArtifact.getArtifactId().equals( d.getArtifact().getArtifactId() );
215
216 processDependency( args, parent, results, repositories, depSelector, depManager, depTraverser,
217 verFilter, d, descriptorResult.getRelocations(), disableVersionManagementSubsequently );
218 return;
219 }
220 else
221 {
222 d = args.pool.intern( d.setArtifact( args.pool.intern( d.getArtifact() ) ) );
223
224 List<RemoteRepository> repos =
225 getRemoteRepositories( rangeResult.getRepository( version ), repositories );
226
227 DefaultDependencyNode child =
228 createDependencyNode( relocations, preManaged, rangeResult, version, d,
229 descriptorResult.getAliases(), repos, args.request.getRequestContext() );
230
231 node.getChildren().add( child );
232
233 boolean recurse = traverse && !descriptorResult.getDependencies().isEmpty();
234 if ( recurse )
235 {
236 doRecurse( args, parent, results, repositories, depSelector, depManager, depTraverser,
237 verFilter, d, descriptorResult, child );
238 }
239 }
240 }
241 else
242 {
243 DependencyNode node = args.nodes.top();
244 List<RemoteRepository> repos =
245 getRemoteRepositories( rangeResult.getRepository( version ), repositories );
246 DefaultDependencyNode child =
247 createDependencyNode( relocations, preManaged, rangeResult, version, d, null, repos,
248 args.request.getRequestContext() );
249 node.getChildren().add( child );
250 }
251 }
252 }
253
254 @SuppressWarnings( "checkstyle:parameternumber" )
255 private void doRecurse( Args args, RequestTrace trace, Results results, List<RemoteRepository> repositories,
256 DependencySelector depSelector, DependencyManager depManager,
257 DependencyTraverser depTraverser, VersionFilter verFilter, Dependency d,
258 ArtifactDescriptorResult descriptorResult, DefaultDependencyNode child )
259 {
260 DefaultDependencyCollectionContext context = args.collectionContext;
261 context.set( d, descriptorResult.getManagedDependencies() );
262
263 DependencySelector childSelector = depSelector != null ? depSelector.deriveChildSelector( context ) : null;
264 DependencyManager childManager = depManager != null ? depManager.deriveChildManager( context ) : null;
265 DependencyTraverser childTraverser = depTraverser != null ? depTraverser.deriveChildTraverser( context ) : null;
266 VersionFilter childFilter = verFilter != null ? verFilter.deriveChildFilter( context ) : null;
267
268 final List<RemoteRepository> childRepos =
269 args.ignoreRepos
270 ? repositories
271 : remoteRepositoryManager.aggregateRepositories( args.session, repositories,
272 descriptorResult.getRepositories(), true );
273
274 Object key =
275 args.pool.toKey( d.getArtifact(), childRepos, childSelector, childManager, childTraverser, childFilter );
276
277 List<DependencyNode> children = args.pool.getChildren( key );
278 if ( children == null )
279 {
280 args.pool.putChildren( key, child.getChildren() );
281
282 args.nodes.push( child );
283
284 process( args, trace, results, descriptorResult.getDependencies(), childRepos, childSelector, childManager,
285 childTraverser, childFilter );
286
287 args.nodes.pop();
288 }
289 else
290 {
291 child.setChildren( children );
292 }
293 }
294
295 private ArtifactDescriptorResult getArtifactDescriptorResult( Args args, Results results, boolean noDescriptor,
296 Dependency d,
297 ArtifactDescriptorRequest descriptorRequest )
298 {
299 return noDescriptor
300 ? new ArtifactDescriptorResult( descriptorRequest )
301 : resolveCachedArtifactDescriptor( args.pool, descriptorRequest, args.session, d, results, args );
302
303 }
304
305 private ArtifactDescriptorResult resolveCachedArtifactDescriptor( DataPool pool,
306 ArtifactDescriptorRequest descriptorRequest,
307 RepositorySystemSession session, Dependency d,
308 Results results, Args args )
309 {
310 Object key = pool.toKey( descriptorRequest );
311 ArtifactDescriptorResult descriptorResult = pool.getDescriptor( key, descriptorRequest );
312 if ( descriptorResult == null )
313 {
314 try
315 {
316 descriptorResult = descriptorReader.readArtifactDescriptor( session, descriptorRequest );
317 pool.putDescriptor( key, descriptorResult );
318 }
319 catch ( ArtifactDescriptorException e )
320 {
321 results.addException( d, e, args.nodes.nodes );
322 pool.putDescriptor( key, e );
323 return null;
324 }
325
326 }
327 else if ( descriptorResult == DataPool.NO_DESCRIPTOR )
328 {
329 return null;
330 }
331
332 return descriptorResult;
333 }
334
335 static class Args
336 {
337
338 final RepositorySystemSession session;
339
340 final boolean ignoreRepos;
341
342 final boolean premanagedState;
343
344 final DataPool pool;
345
346 final NodeStack nodes;
347
348 final DefaultDependencyCollectionContext collectionContext;
349
350 final DefaultVersionFilterContext versionContext;
351
352 final CollectRequest request;
353
354 Args( RepositorySystemSession session, DataPool pool, NodeStack nodes,
355 DefaultDependencyCollectionContext collectionContext, DefaultVersionFilterContext versionContext,
356 CollectRequest request )
357 {
358 this.session = session;
359 this.request = request;
360 this.ignoreRepos = session.isIgnoreArtifactDescriptorRepositories();
361 this.premanagedState = ConfigUtils.getBoolean( session, false, DependencyManagerUtils.CONFIG_PROP_VERBOSE );
362 this.pool = pool;
363 this.nodes = nodes;
364 this.collectionContext = collectionContext;
365 this.versionContext = versionContext;
366 }
367
368 }
369 }