View Javadoc
1   package org.eclipse.aether.internal.impl.collect;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   * 
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   * 
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
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 }