1 package org.eclipse.aether.internal.impl.collect;
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.HashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Objects;
27 import java.util.WeakHashMap;
28 import java.util.concurrent.ExecutionException;
29 import java.util.concurrent.Future;
30 import java.util.concurrent.TimeUnit;
31 import java.util.concurrent.TimeoutException;
32
33 import org.eclipse.aether.RepositoryCache;
34 import org.eclipse.aether.RepositorySystemSession;
35 import org.eclipse.aether.artifact.Artifact;
36 import org.eclipse.aether.collection.DependencyManager;
37 import org.eclipse.aether.collection.DependencySelector;
38 import org.eclipse.aether.collection.DependencyTraverser;
39 import org.eclipse.aether.collection.VersionFilter;
40 import org.eclipse.aether.graph.Dependency;
41 import org.eclipse.aether.graph.DependencyNode;
42 import org.eclipse.aether.repository.ArtifactRepository;
43 import org.eclipse.aether.repository.RemoteRepository;
44 import org.eclipse.aether.resolution.ArtifactDescriptorException;
45 import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
46 import org.eclipse.aether.resolution.ArtifactDescriptorResult;
47 import org.eclipse.aether.resolution.VersionRangeRequest;
48 import org.eclipse.aether.resolution.VersionRangeResult;
49 import org.eclipse.aether.util.concurrency.FutureResult;
50 import org.eclipse.aether.version.Version;
51 import org.eclipse.aether.version.VersionConstraint;
52
53
54
55 final class DataPool
56 {
57
58 private static final String ARTIFACT_POOL = DataPool.class.getName() + "$Artifact";
59
60 private static final String DEPENDENCY_POOL = DataPool.class.getName() + "$Dependency";
61
62 private static final String DESCRIPTORS = DataPool.class.getName() + "$Descriptors";
63
64 public static final Future<ArtifactDescriptorResult> NO_DESCRIPTOR =
65 new FutureResult<>( new ArtifactDescriptorResult( new ArtifactDescriptorRequest() ) );
66
67 private ObjectPool<Artifact> artifacts;
68
69 private ObjectPool<Dependency> dependencies;
70
71 private Map<Object, Descriptor> descriptors;
72
73 private Map<Object, Constraint> constraints = new HashMap<>();
74
75 private Map<Object, List<DependencyNode>> nodes = new HashMap<>( 256 );
76
77 @SuppressWarnings( "unchecked" )
78 DataPool( RepositorySystemSession session )
79 {
80 RepositoryCache cache = session.getCache();
81
82 if ( cache != null )
83 {
84 artifacts = (ObjectPool<Artifact>) cache.get( session, ARTIFACT_POOL );
85 dependencies = (ObjectPool<Dependency>) cache.get( session, DEPENDENCY_POOL );
86 descriptors = (Map<Object, Descriptor>) cache.get( session, DESCRIPTORS );
87 }
88
89 if ( artifacts == null )
90 {
91 artifacts = new ObjectPool<>();
92 if ( cache != null )
93 {
94 cache.put( session, ARTIFACT_POOL, artifacts );
95 }
96 }
97
98 if ( dependencies == null )
99 {
100 dependencies = new ObjectPool<>();
101 if ( cache != null )
102 {
103 cache.put( session, DEPENDENCY_POOL, dependencies );
104 }
105 }
106
107 if ( descriptors == null )
108 {
109 descriptors = Collections.synchronizedMap( new WeakHashMap<Object, Descriptor>( 256 ) );
110 if ( cache != null )
111 {
112 cache.put( session, DESCRIPTORS, descriptors );
113 }
114 }
115 }
116
117 public Artifact intern( Artifact artifact )
118 {
119 return artifacts.intern( artifact );
120 }
121
122 public Dependency intern( Dependency dependency )
123 {
124 return dependencies.intern( dependency );
125 }
126
127 public Object toKey( ArtifactDescriptorRequest request )
128 {
129 return request.getArtifact();
130 }
131
132 public Future<ArtifactDescriptorResult> getDescriptor( Object key, ArtifactDescriptorRequest request )
133 {
134 Descriptor descriptor = descriptors.get( key );
135 if ( descriptor != null )
136 {
137 return descriptor.toResult( request );
138 }
139 return null;
140 }
141
142 public void putDescriptor( Object key, Future<ArtifactDescriptorResult> futureResult )
143 {
144 descriptors.put( key, new GoodDescriptor( futureResult ) );
145 }
146
147 public void putDescriptor( Object key, ArtifactDescriptorException exception )
148 {
149 descriptors.put( key, BadDescriptor.INSTANCE );
150 }
151
152 public Object toKey( VersionRangeRequest request )
153 {
154 return new ConstraintKey( request );
155 }
156
157 public VersionRangeResult getConstraint( Object key, VersionRangeRequest request )
158 {
159 Constraint constraint = constraints.get( key );
160 if ( constraint != null )
161 {
162 return constraint.toResult( request );
163 }
164 return null;
165 }
166
167 public void putConstraint( Object key, VersionRangeResult result )
168 {
169 constraints.put( key, new Constraint( result ) );
170 }
171
172 public Object toKey( Artifact artifact, DefaultDependencyCollectionContext context )
173 {
174 return new GraphKey( artifact, context.getRepositories(), context.getDepSelector(),
175 context.getDepManager(), context.getDepTraverser(), context.getVerFilter() );
176 }
177
178 public List<DependencyNode> getChildren( Object key )
179 {
180 return nodes.get( key );
181 }
182
183 public void putChildren( Object key, List<DependencyNode> children )
184 {
185 nodes.put( key, children );
186 }
187
188 abstract static class Descriptor
189 {
190 public abstract Future<ArtifactDescriptorResult> toResult( ArtifactDescriptorRequest request );
191 }
192
193 static final class GoodDescriptor
194 extends Descriptor
195 {
196 Future<ArtifactDescriptorResult> futureResult;
197
198 GoodDescriptor( Future<ArtifactDescriptorResult> futureResult )
199 {
200 this.futureResult = futureResult;
201 }
202
203 public Future<ArtifactDescriptorResult> toResult( final ArtifactDescriptorRequest request )
204 {
205 return new Future<ArtifactDescriptorResult>()
206 {
207 public boolean cancel( boolean mayInterruptIfRunning )
208 {
209 return futureResult.cancel( mayInterruptIfRunning );
210 }
211
212 public boolean isCancelled()
213 {
214 return futureResult.isCancelled();
215 }
216
217 public boolean isDone()
218 {
219 return futureResult.isDone();
220 }
221
222 public ArtifactDescriptorResult get()
223 throws InterruptedException, ExecutionException
224 {
225 ArtifactDescriptorResult result = futureResult.get();
226 return wrap( request, result );
227 }
228 public ArtifactDescriptorResult get( long timeout, TimeUnit unit )
229 throws InterruptedException, ExecutionException, TimeoutException
230 {
231 ArtifactDescriptorResult result = futureResult.get( timeout, unit );
232 return wrap( request, result );
233 }
234 };
235 }
236
237 private ArtifactDescriptorResult wrap( ArtifactDescriptorRequest request, ArtifactDescriptorResult result )
238 {
239 ArtifactDescriptorResult wrapped = new ArtifactDescriptorResult( request );
240 wrapped.setArtifact( result.getArtifact() );
241 wrapped.setRelocations( result.getRelocations() );
242 wrapped.setAliases( result.getAliases() );
243 wrapped.setDependencies( result.getDependencies() );
244 wrapped.setManagedDependencies( result.getManagedDependencies() );
245 wrapped.setRepositories( result.getRepositories() );
246 return wrapped;
247 }
248 }
249
250 static final class BadDescriptor
251 extends Descriptor
252 {
253 static final BadDescriptor INSTANCE = new BadDescriptor();
254
255 public Future<ArtifactDescriptorResult> toResult( ArtifactDescriptorRequest request )
256 {
257 return NO_DESCRIPTOR;
258 }
259 }
260
261 static final class Constraint
262 {
263 final VersionRepo[] repositories;
264
265 final VersionConstraint versionConstraint;
266
267 Constraint( VersionRangeResult result )
268 {
269 versionConstraint = result.getVersionConstraint();
270 List<Version> versions = result.getVersions();
271 repositories = new VersionRepo[versions.size()];
272 int i = 0;
273 for ( Version version : versions )
274 {
275 repositories[i++] = new VersionRepo( version, result.getRepository( version ) );
276 }
277 }
278
279 public VersionRangeResult toResult( VersionRangeRequest request )
280 {
281 VersionRangeResult result = new VersionRangeResult( request );
282 for ( VersionRepo vr : repositories )
283 {
284 result.addVersion( vr.version );
285 result.setRepository( vr.version, vr.repo );
286 }
287 result.setVersionConstraint( versionConstraint );
288 return result;
289 }
290
291 static final class VersionRepo
292 {
293 final Version version;
294
295 final ArtifactRepository repo;
296
297 VersionRepo( Version version, ArtifactRepository repo )
298 {
299 this.version = version;
300 this.repo = repo;
301 }
302 }
303 }
304
305 static final class ConstraintKey
306 {
307 private final Artifact artifact;
308
309 private final List<RemoteRepository> repositories;
310
311 private final int hashCode;
312
313 ConstraintKey( VersionRangeRequest request )
314 {
315 artifact = request.getArtifact();
316 repositories = request.getRepositories();
317 hashCode = artifact.hashCode();
318 }
319
320 @Override
321 public boolean equals( Object obj )
322 {
323 if ( obj == this )
324 {
325 return true;
326 }
327 else if ( !( obj instanceof ConstraintKey ) )
328 {
329 return false;
330 }
331 ConstraintKey that = (ConstraintKey) obj;
332 return artifact.equals( that.artifact ) && equals( repositories, that.repositories );
333 }
334
335 private static boolean equals( List<RemoteRepository> repos1, List<RemoteRepository> repos2 )
336 {
337 if ( repos1.size() != repos2.size() )
338 {
339 return false;
340 }
341 for ( int i = 0, n = repos1.size(); i < n; i++ )
342 {
343 RemoteRepository repo1 = repos1.get( i );
344 RemoteRepository repo2 = repos2.get( i );
345 if ( repo1.isRepositoryManager() != repo2.isRepositoryManager() )
346 {
347 return false;
348 }
349 if ( repo1.isRepositoryManager() )
350 {
351 if ( !equals( repo1.getMirroredRepositories(), repo2.getMirroredRepositories() ) )
352 {
353 return false;
354 }
355 }
356 else if ( !repo1.getUrl().equals( repo2.getUrl() ) )
357 {
358 return false;
359 }
360 else if ( repo1.getPolicy( true ).isEnabled() != repo2.getPolicy( true ).isEnabled() )
361 {
362 return false;
363 }
364 else if ( repo1.getPolicy( false ).isEnabled() != repo2.getPolicy( false ).isEnabled() )
365 {
366 return false;
367 }
368 }
369 return true;
370 }
371
372 @Override
373 public int hashCode()
374 {
375 return hashCode;
376 }
377 }
378
379 static final class GraphKey
380 {
381 private final Artifact artifact;
382
383 private final List<RemoteRepository> repositories;
384
385 private final DependencySelector selector;
386
387 private final DependencyManager manager;
388
389 private final DependencyTraverser traverser;
390
391 private final VersionFilter filter;
392
393 private final int hashCode;
394
395 GraphKey( Artifact artifact, List<RemoteRepository> repositories, DependencySelector selector,
396 DependencyManager manager, DependencyTraverser traverser, VersionFilter filter )
397 {
398 this.artifact = artifact;
399 this.repositories = repositories;
400 this.selector = selector;
401 this.manager = manager;
402 this.traverser = traverser;
403 this.filter = filter;
404
405 hashCode = Objects.hash( artifact, repositories, selector, manager, traverser, filter );
406 }
407
408 @Override
409 public boolean equals( Object obj )
410 {
411 if ( obj == this )
412 {
413 return true;
414 }
415 else if ( !( obj instanceof GraphKey ) )
416 {
417 return false;
418 }
419 GraphKey that = (GraphKey) obj;
420 return Objects.equals( artifact, that.artifact ) && Objects.equals( repositories, that.repositories )
421 && Objects.equals( selector, that.selector ) && Objects.equals( manager, that.manager )
422 && Objects.equals( traverser, that.traverser ) && Objects.equals( filter, that.filter );
423 }
424
425 @Override
426 public int hashCode()
427 {
428 return hashCode;
429 }
430 }
431 }