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.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 }