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