View Javadoc
1   package org.apache.maven.project.artifact;
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.ArrayList;
23  import java.util.Collection;
24  import java.util.Collections;
25  import java.util.HashSet;
26  import java.util.LinkedHashSet;
27  import java.util.List;
28  import java.util.Map;
29  import java.util.Objects;
30  import java.util.Set;
31  import java.util.concurrent.ConcurrentHashMap;
32  
33  import org.apache.maven.RepositoryUtils;
34  import org.apache.maven.artifact.Artifact;
35  import org.apache.maven.lifecycle.LifecycleExecutionException;
36  import org.apache.maven.project.MavenProject;
37  import org.codehaus.plexus.component.annotations.Component;
38  import org.eclipse.aether.RepositorySystemSession;
39  import org.eclipse.aether.repository.LocalRepository;
40  import org.eclipse.aether.repository.RemoteRepository;
41  import org.eclipse.aether.repository.WorkspaceRepository;
42  
43  /**
44   * @author Igor Fedorenko
45   * @author Benjamin Bentmann
46   * @author Anton Tanasenko
47   */
48  @Component( role = ProjectArtifactsCache.class )
49  public class DefaultProjectArtifactsCache
50      implements ProjectArtifactsCache
51  {
52      /**
53       * CacheKey
54       */
55      protected static class CacheKey
56          implements Key
57      {
58  
59          private final String groupId;
60          
61          private final String artifactId;
62          
63          private final String version;
64          
65          private final Set<String> dependencyArtifacts;
66  
67          private final WorkspaceRepository workspace;
68  
69          private final LocalRepository localRepo;
70  
71          private final List<RemoteRepository> repositories;
72          
73          private final Set<String> collect;
74          
75          private final Set<String> resolve;
76          
77          private boolean aggregating;
78  
79          private final int hashCode;
80  
81          public CacheKey( MavenProject project, List<RemoteRepository> repositories,
82              Collection<String> scopesToCollect, Collection<String> scopesToResolve, boolean aggregating,
83              RepositorySystemSession session )
84          {
85              
86              groupId = project.getGroupId();
87              artifactId = project.getArtifactId();
88              version = project.getVersion();
89              
90              Set<String> deps = new LinkedHashSet<>();
91              if ( project.getDependencyArtifacts() != null )
92              {
93                for ( Artifact dep: project.getDependencyArtifacts() )
94                {
95                  deps.add( dep.toString() );
96                }
97              }
98              dependencyArtifacts = Collections.unmodifiableSet( deps );
99              
100             workspace = RepositoryUtils.getWorkspace( session );
101             this.localRepo = session.getLocalRepository();
102             this.repositories = new ArrayList<>( repositories.size() );
103             for ( RemoteRepository repository : repositories )
104             {
105                 if ( repository.isRepositoryManager() )
106                 {
107                     this.repositories.addAll( repository.getMirroredRepositories() );
108                 }
109                 else
110                 {
111                     this.repositories.add( repository );
112                 }
113             }
114             collect = scopesToCollect == null
115                 ? Collections.<String>emptySet() 
116                 : Collections.unmodifiableSet( new HashSet<>( scopesToCollect ) );
117             resolve = scopesToResolve == null 
118                 ? Collections.<String>emptySet() 
119                 : Collections.unmodifiableSet( new HashSet<>( scopesToResolve ) );
120             this.aggregating = aggregating;
121 
122             int hash = 17;
123             hash = hash * 31 + Objects.hashCode( groupId );
124             hash = hash * 31 + Objects.hashCode( artifactId );
125             hash = hash * 31 + Objects.hashCode( version );
126             hash = hash * 31 + Objects.hashCode( dependencyArtifacts );
127             hash = hash * 31 + Objects.hashCode( workspace );
128             hash = hash * 31 + Objects.hashCode( localRepo );
129             hash = hash * 31 + RepositoryUtils.repositoriesHashCode( repositories );
130             hash = hash * 31 + Objects.hashCode( collect );
131             hash = hash * 31 + Objects.hashCode( resolve );
132             hash = hash * 31 + Objects.hashCode( aggregating );
133             this.hashCode = hash;
134         }
135 
136         @Override
137         public String toString()
138         {
139             return groupId + ":" + artifactId + ":" + version;
140         }
141 
142         @Override
143         public int hashCode()
144         {
145             return hashCode;
146         }
147 
148         @Override
149         public boolean equals( Object o )
150         {
151             if ( o == this )
152             {
153                 return true;
154             }
155 
156             if ( !( o instanceof CacheKey ) )
157             {
158                 return false;
159             }
160 
161             CacheKey that = (CacheKey) o;
162 
163             return Objects.equals( groupId, that.groupId ) && Objects.equals( artifactId, that.artifactId )
164                 && Objects.equals( version, that.version )
165                 && Objects.equals( dependencyArtifacts, that.dependencyArtifacts )
166                 && Objects.equals( workspace, that.workspace ) 
167                 && Objects.equals( localRepo, that.localRepo )
168                 && RepositoryUtils.repositoriesEquals( repositories, that.repositories )
169                 && Objects.equals( collect, that.collect ) 
170                 && Objects.equals( resolve, that.resolve )
171                 && aggregating == that.aggregating;
172         }
173     }
174 
175     protected final Map<Key, CacheRecord> cache = new ConcurrentHashMap<>();
176 
177     @Override
178     public Key createKey( MavenProject project, Collection<String> scopesToCollect,
179         Collection<String> scopesToResolve, boolean aggregating, RepositorySystemSession session )
180     {
181         return new CacheKey( project, project.getRemoteProjectRepositories(), scopesToCollect, scopesToResolve, 
182             aggregating, session );
183     }
184 
185     @Override
186     public CacheRecord get( Key key )
187         throws LifecycleExecutionException
188     {
189         CacheRecord cacheRecord = cache.get( key );
190 
191         if ( cacheRecord != null && cacheRecord.getException() != null )
192         {
193             throw cacheRecord.getException();
194         }
195 
196         return cacheRecord;
197     }
198 
199     @Override
200     public CacheRecord put( Key key, Set<Artifact> projectArtifacts )
201     {
202         Objects.requireNonNull( projectArtifacts, "projectArtifacts cannot be null" );
203 
204         assertUniqueKey( key );
205 
206         CacheRecord record =
207             new CacheRecord( Collections.unmodifiableSet( new LinkedHashSet<>( projectArtifacts ) ) );
208 
209         cache.put( key, record );
210 
211         return record;
212     }
213 
214     protected void assertUniqueKey( Key key )
215     {
216         if ( cache.containsKey( key ) )
217         {
218             throw new IllegalStateException( "Duplicate artifact resolution result for project " + key );
219         }
220     }
221 
222     @Override
223     public CacheRecord put( Key key, LifecycleExecutionException exception )
224     {
225         Objects.requireNonNull( exception, "exception cannot be null" );
226 
227         assertUniqueKey( key );
228 
229         CacheRecord record = new CacheRecord( exception );
230 
231         cache.put( key, record );
232 
233         return record;
234     }
235 
236     @Override
237     public void flush()
238     {
239         cache.clear();
240     }
241 
242     @Override
243     public void register( MavenProject project, Key cacheKey, CacheRecord record )
244     {
245         // default cache does not track record usage
246     }
247 
248 }