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