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