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