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.lang.ref.WeakReference;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Objects;
30 import java.util.WeakHashMap;
31
32 import org.eclipse.aether.RepositoryCache;
33 import org.eclipse.aether.RepositorySystemSession;
34 import org.eclipse.aether.artifact.Artifact;
35 import org.eclipse.aether.collection.DependencyManager;
36 import org.eclipse.aether.collection.DependencySelector;
37 import org.eclipse.aether.collection.DependencyTraverser;
38 import org.eclipse.aether.collection.VersionFilter;
39 import org.eclipse.aether.graph.Dependency;
40 import org.eclipse.aether.graph.DependencyNode;
41 import org.eclipse.aether.repository.ArtifactRepository;
42 import org.eclipse.aether.repository.RemoteRepository;
43 import org.eclipse.aether.resolution.ArtifactDescriptorException;
44 import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
45 import org.eclipse.aether.resolution.ArtifactDescriptorResult;
46 import org.eclipse.aether.resolution.VersionRangeRequest;
47 import org.eclipse.aether.resolution.VersionRangeResult;
48 import org.eclipse.aether.version.Version;
49 import org.eclipse.aether.version.VersionConstraint;
50
51
52
53
54 public final class DataPool
55 {
56
57 private static final String ARTIFACT_POOL = DataPool.class.getName() + "$Artifact";
58
59 private static final String DEPENDENCY_POOL = DataPool.class.getName() + "$Dependency";
60
61 private static final String DESCRIPTORS = DataPool.class.getName() + "$Descriptors";
62
63 public static final ArtifactDescriptorResult NO_DESCRIPTOR =
64 new ArtifactDescriptorResult( new ArtifactDescriptorRequest() );
65
66 private ObjectPool<Artifact> artifacts;
67
68 private ObjectPool<Dependency> dependencies;
69
70 private Map<Object, WeakReference<Descriptor>> descriptors;
71
72 private final Map<Object, Constraint> constraints = new HashMap<>();
73
74 private final Map<Object, List<DependencyNode>> nodes = new HashMap<>( 256 );
75
76 @SuppressWarnings( "unchecked" )
77 public DataPool( RepositorySystemSession session )
78 {
79 RepositoryCache cache = session.getCache();
80
81 if ( cache != null )
82 {
83 artifacts = (ObjectPool<Artifact>) cache.get( session, ARTIFACT_POOL );
84 dependencies = (ObjectPool<Dependency>) cache.get( session, DEPENDENCY_POOL );
85 descriptors = (Map<Object, WeakReference<Descriptor>>) cache.get( session, DESCRIPTORS );
86 }
87
88 if ( artifacts == null )
89 {
90 artifacts = new ObjectPool<>();
91 if ( cache != null )
92 {
93 cache.put( session, ARTIFACT_POOL, artifacts );
94 }
95 }
96
97 if ( dependencies == null )
98 {
99 dependencies = new ObjectPool<>();
100 if ( cache != null )
101 {
102 cache.put( session, DEPENDENCY_POOL, dependencies );
103 }
104 }
105
106 if ( descriptors == null )
107 {
108 descriptors = Collections.synchronizedMap( new WeakHashMap<>( 256 ) );
109 if ( cache != null )
110 {
111 cache.put( session, DESCRIPTORS, descriptors );
112 }
113 }
114 }
115
116 public Artifact intern( Artifact artifact )
117 {
118 return artifacts.intern( artifact );
119 }
120
121 public Dependency intern( Dependency dependency )
122 {
123 return dependencies.intern( dependency );
124 }
125
126 public Object toKey( ArtifactDescriptorRequest request )
127 {
128 return request.getArtifact();
129 }
130
131 public ArtifactDescriptorResult getDescriptor( Object key, ArtifactDescriptorRequest request )
132 {
133 WeakReference<Descriptor> descriptorRef = descriptors.get( key );
134 Descriptor descriptor = descriptorRef != null ? descriptorRef.get() : null;
135 if ( descriptor != null )
136 {
137 return descriptor.toResult( request );
138 }
139 return null;
140 }
141
142 public void putDescriptor( Object key, ArtifactDescriptorResult result )
143 {
144 descriptors.put( key, new WeakReference<>( new GoodDescriptor( result ) ) );
145 }
146
147 public void putDescriptor( Object key, ArtifactDescriptorException e )
148 {
149 descriptors.put( key, new WeakReference<>( 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, List<RemoteRepository> repositories, DependencySelector selector,
173 DependencyManager manager, DependencyTraverser traverser, VersionFilter filter )
174 {
175 return new GraphKey( artifact, repositories, selector, manager, traverser, filter );
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
191 public abstract ArtifactDescriptorResult toResult( ArtifactDescriptorRequest request );
192
193 }
194
195 static final class GoodDescriptor
196 extends Descriptor
197 {
198
199 final Artifact artifact;
200
201 final List<Artifact> relocations;
202
203 final Collection<Artifact> aliases;
204
205 final List<RemoteRepository> repositories;
206
207 final List<Dependency> dependencies;
208
209 final List<Dependency> managedDependencies;
210
211 GoodDescriptor( ArtifactDescriptorResult result )
212 {
213 artifact = result.getArtifact();
214 relocations = result.getRelocations();
215 aliases = result.getAliases();
216 dependencies = result.getDependencies();
217 managedDependencies = result.getManagedDependencies();
218 repositories = result.getRepositories();
219 }
220
221 public ArtifactDescriptorResult toResult( ArtifactDescriptorRequest request )
222 {
223 ArtifactDescriptorResult result = new ArtifactDescriptorResult( request );
224 result.setArtifact( artifact );
225 result.setRelocations( relocations );
226 result.setAliases( aliases );
227 result.setDependencies( dependencies );
228 result.setManagedDependencies( managedDependencies );
229 result.setRepositories( repositories );
230 return result;
231 }
232
233 }
234
235 static final class BadDescriptor
236 extends Descriptor
237 {
238
239 static final BadDescriptor INSTANCE = new BadDescriptor();
240
241 public ArtifactDescriptorResult toResult( ArtifactDescriptorRequest request )
242 {
243 return NO_DESCRIPTOR;
244 }
245 }
246
247 private static final class Constraint
248 {
249 final VersionRepo[] repositories;
250
251 final VersionConstraint versionConstraint;
252
253 Constraint( VersionRangeResult result )
254 {
255 versionConstraint = result.getVersionConstraint();
256 List<Version> versions = result.getVersions();
257 repositories = new VersionRepo[versions.size()];
258 int i = 0;
259 for ( Version version : versions )
260 {
261 repositories[i++] = new VersionRepo( version, result.getRepository( version ) );
262 }
263 }
264
265 VersionRangeResult toResult( VersionRangeRequest request )
266 {
267 VersionRangeResult result = new VersionRangeResult( request );
268 for ( VersionRepo vr : repositories )
269 {
270 result.addVersion( vr.version );
271 result.setRepository( vr.version, vr.repo );
272 }
273 result.setVersionConstraint( versionConstraint );
274 return result;
275 }
276
277 static final class VersionRepo
278 {
279 final Version version;
280
281 final ArtifactRepository repo;
282
283 VersionRepo( Version version, ArtifactRepository repo )
284 {
285 this.version = version;
286 this.repo = repo;
287 }
288 }
289 }
290
291 static final class ConstraintKey
292 {
293 private final Artifact artifact;
294
295 private final List<RemoteRepository> repositories;
296
297 private final int hashCode;
298
299 ConstraintKey( VersionRangeRequest request )
300 {
301 artifact = request.getArtifact();
302 repositories = request.getRepositories();
303 hashCode = artifact.hashCode();
304 }
305
306 @Override
307 public boolean equals( Object obj )
308 {
309 if ( obj == this )
310 {
311 return true;
312 }
313 else if ( !( obj instanceof ConstraintKey ) )
314 {
315 return false;
316 }
317 ConstraintKey that = (ConstraintKey) obj;
318 return artifact.equals( that.artifact ) && equals( repositories, that.repositories );
319 }
320
321 private static boolean equals( List<RemoteRepository> repos1, List<RemoteRepository> repos2 )
322 {
323 if ( repos1.size() != repos2.size() )
324 {
325 return false;
326 }
327 for ( Iterator<RemoteRepository> it1 = repos1.iterator(), it2 = repos2.iterator();
328 it1.hasNext() && it2.hasNext(); )
329 {
330 RemoteRepository repo1 = it1.next();
331 RemoteRepository repo2 = it2.next();
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 static final class GraphKey
367 {
368 private final Artifact artifact;
369
370 private final List<RemoteRepository> repositories;
371
372 private final DependencySelector selector;
373
374 private final DependencyManager manager;
375
376 private final DependencyTraverser traverser;
377
378 private final VersionFilter filter;
379
380 private final int hashCode;
381
382 GraphKey( Artifact artifact, List<RemoteRepository> repositories, DependencySelector selector,
383 DependencyManager manager, DependencyTraverser traverser, VersionFilter filter )
384 {
385 this.artifact = artifact;
386 this.repositories = repositories;
387 this.selector = selector;
388 this.manager = manager;
389 this.traverser = traverser;
390 this.filter = filter;
391
392 hashCode = Objects.hash( artifact, repositories, selector, manager, traverser, filter );
393 }
394
395 @Override
396 public boolean equals( Object obj )
397 {
398 if ( obj == this )
399 {
400 return true;
401 }
402 else if ( !( obj instanceof GraphKey ) )
403 {
404 return false;
405 }
406 GraphKey that = (GraphKey) obj;
407 return Objects.equals( artifact, that.artifact ) && Objects.equals( repositories, that.repositories )
408 && Objects.equals( selector, that.selector ) && Objects.equals( manager, that.manager )
409 && Objects.equals( traverser, that.traverser ) && Objects.equals( filter, that.filter );
410 }
411
412 @Override
413 public int hashCode()
414 {
415 return hashCode;
416 }
417 }
418 }