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