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.io.File;
25 import java.util.ArrayList;
26 import java.util.Iterator;
27 import java.util.LinkedHashMap;
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.artifact.Artifact;
36 import org.apache.maven.artifact.ArtifactUtils;
37 import org.apache.maven.artifact.metadata.ResolutionGroup;
38 import org.apache.maven.artifact.repository.ArtifactRepository;
39 import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
40
41
42
43
44 @Named
45 @Singleton
46 @Deprecated
47 public class DefaultMavenMetadataCache implements MavenMetadataCache {
48
49 protected final Map<CacheKey, CacheRecord> cache = new ConcurrentHashMap<>();
50
51
52
53
54 public static class CacheKey {
55 private final Artifact artifact;
56 private final long pomHash;
57 private final boolean resolveManagedVersions;
58 private final List<ArtifactRepository> repositories = new ArrayList<>();
59 private final int hashCode;
60
61 public CacheKey(
62 Artifact artifact,
63 boolean resolveManagedVersions,
64 ArtifactRepository localRepository,
65 List<ArtifactRepository> remoteRepositories) {
66 File file = artifact.getFile();
67 this.artifact = ArtifactUtils.copyArtifact(artifact);
68 if ("pom".equals(artifact.getType()) && file != null) {
69 pomHash = file.getPath().hashCode() + file.lastModified();
70 } else {
71 pomHash = 0;
72 }
73 this.resolveManagedVersions = resolveManagedVersions;
74 this.repositories.add(localRepository);
75 this.repositories.addAll(remoteRepositories);
76
77 int hash = 17;
78 hash = hash * 31 + artifactHashCode(artifact);
79 hash = hash * 31 + (resolveManagedVersions ? 1 : 2);
80 hash = hash * 31 + repositoriesHashCode(repositories);
81 this.hashCode = hash;
82 }
83
84 @Override
85 public int hashCode() {
86 return hashCode;
87 }
88
89 @Override
90 public boolean equals(Object o) {
91 if (o == this) {
92 return true;
93 }
94
95 if (o instanceof CacheKey other) {
96 return pomHash == other.pomHash
97 && artifactEquals(artifact, other.artifact)
98 && resolveManagedVersions == other.resolveManagedVersions
99 && repositoriesEquals(repositories, other.repositories);
100 } else {
101 return false;
102 }
103 }
104 }
105
106 private static int artifactHashCode(Artifact a) {
107 int result = 17;
108 result = 31 * result + a.getGroupId().hashCode();
109 result = 31 * result + a.getArtifactId().hashCode();
110 result = 31 * result + a.getType().hashCode();
111 if (a.getVersion() != null) {
112 result = 31 * result + a.getVersion().hashCode();
113 }
114 result = 31 * result + (a.getClassifier() != null ? a.getClassifier().hashCode() : 0);
115 result = 31 * result + (a.getScope() != null ? a.getScope().hashCode() : 0);
116 result = 31 * result
117 + (a.getDependencyFilter() != null ? a.getDependencyFilter().hashCode() : 0);
118 result = 31 * result + (a.isOptional() ? 1 : 0);
119 return result;
120 }
121
122 private static boolean artifactEquals(Artifact a1, Artifact a2) {
123 if (a1 == a2) {
124 return true;
125 }
126
127 return Objects.equals(a1.getGroupId(), a2.getGroupId())
128 && Objects.equals(a1.getArtifactId(), a2.getArtifactId())
129 && Objects.equals(a1.getType(), a2.getType())
130 && Objects.equals(a1.getVersion(), a2.getVersion())
131 && Objects.equals(a1.getClassifier(), a2.getClassifier())
132 && Objects.equals(a1.getScope(), a2.getScope())
133 && Objects.equals(a1.getDependencyFilter(), a2.getDependencyFilter())
134 && a1.isOptional() == a2.isOptional();
135 }
136
137 private static int repositoryHashCode(ArtifactRepository repository) {
138 int result = 17;
139 result = 31 * result + (repository.getId() != null ? repository.getId().hashCode() : 0);
140 return result;
141 }
142
143 private static int repositoriesHashCode(List<ArtifactRepository> repositories) {
144 int result = 17;
145 for (ArtifactRepository repository : repositories) {
146 result = 31 * result + repositoryHashCode(repository);
147 }
148 return result;
149 }
150
151 private static boolean repositoryEquals(ArtifactRepository r1, ArtifactRepository r2) {
152 if (r1 == r2) {
153 return true;
154 }
155
156 return Objects.equals(r1.getId(), r2.getId())
157 && Objects.equals(r1.getUrl(), r2.getUrl())
158 && repositoryPolicyEquals(r1.getReleases(), r2.getReleases())
159 && repositoryPolicyEquals(r1.getSnapshots(), r2.getSnapshots());
160 }
161
162 private static boolean repositoryPolicyEquals(ArtifactRepositoryPolicy p1, ArtifactRepositoryPolicy p2) {
163 if (p1 == p2) {
164 return true;
165 }
166
167 return p1.isEnabled() == p2.isEnabled() && Objects.equals(p1.getUpdatePolicy(), p2.getUpdatePolicy());
168 }
169
170 private static boolean repositoriesEquals(List<ArtifactRepository> r1, List<ArtifactRepository> r2) {
171 if (r1.size() != r2.size()) {
172 return false;
173 }
174
175 for (Iterator<ArtifactRepository> it1 = r1.iterator(), it2 = r2.iterator(); it1.hasNext(); ) {
176 if (!repositoryEquals(it1.next(), it2.next())) {
177 return false;
178 }
179 }
180
181 return true;
182 }
183
184
185
186
187 public class CacheRecord {
188 private Artifact pomArtifact;
189 private Artifact relocatedArtifact;
190 private List<Artifact> artifacts;
191 private Map<String, Artifact> managedVersions;
192 private List<ArtifactRepository> remoteRepositories;
193
194 private long length;
195 private long timestamp;
196
197 CacheRecord(
198 Artifact pomArtifact,
199 Artifact relocatedArtifact,
200 Set<Artifact> artifacts,
201 Map<String, Artifact> managedVersions,
202 List<ArtifactRepository> remoteRepositories) {
203 this.pomArtifact = ArtifactUtils.copyArtifact(pomArtifact);
204 this.relocatedArtifact = ArtifactUtils.copyArtifactSafe(relocatedArtifact);
205 this.artifacts = ArtifactUtils.copyArtifacts(artifacts, new ArrayList<>());
206 this.remoteRepositories = new ArrayList<>(remoteRepositories);
207
208 this.managedVersions = managedVersions;
209 if (managedVersions != null) {
210 this.managedVersions = ArtifactUtils.copyArtifacts(managedVersions, new LinkedHashMap<>());
211 }
212
213 File pomFile = pomArtifact.getFile();
214 if (pomFile != null && pomFile.canRead()) {
215 this.length = pomFile.length();
216 this.timestamp = pomFile.lastModified();
217 } else {
218 this.length = -1;
219 this.timestamp = -1;
220 }
221 }
222
223 public Artifact getArtifact() {
224 return pomArtifact;
225 }
226
227 public Artifact getRelocatedArtifact() {
228 return relocatedArtifact;
229 }
230
231 public List<Artifact> getArtifacts() {
232 return artifacts;
233 }
234
235 public Map<String, Artifact> getManagedVersions() {
236 return managedVersions;
237 }
238
239 public List<ArtifactRepository> getRemoteRepositories() {
240 return remoteRepositories;
241 }
242
243 public boolean isStale() {
244 File pomFile = pomArtifact.getFile();
245 if (pomFile != null) {
246 if (pomFile.canRead()) {
247 return length != pomFile.length() || timestamp != pomFile.lastModified();
248 } else {
249
250 boolean snapshot = pomArtifact.isSnapshot();
251 for (ArtifactRepository repository : remoteRepositories) {
252 ArtifactRepositoryPolicy policy =
253 snapshot ? repository.getSnapshots() : repository.getReleases();
254 if (ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS.equals(policy.getUpdatePolicy())) {
255 return true;
256 }
257 }
258 }
259 }
260
261 return length != -1 || timestamp != -1;
262 }
263 }
264
265 public ResolutionGroup get(
266 Artifact artifact,
267 boolean resolveManagedVersions,
268 ArtifactRepository localRepository,
269 List<ArtifactRepository> remoteRepositories) {
270 CacheKey cacheKey = newCacheKey(artifact, resolveManagedVersions, localRepository, remoteRepositories);
271
272 CacheRecord cacheRecord = cache.get(cacheKey);
273
274 if (cacheRecord != null && !cacheRecord.isStale()) {
275 Artifact pomArtifact = ArtifactUtils.copyArtifact(cacheRecord.getArtifact());
276 Artifact relocatedArtifact = ArtifactUtils.copyArtifactSafe(cacheRecord.getRelocatedArtifact());
277 Set<Artifact> artifacts = ArtifactUtils.copyArtifacts(cacheRecord.getArtifacts(), new LinkedHashSet<>());
278 Map<String, Artifact> managedVersions = cacheRecord.getManagedVersions();
279 if (managedVersions != null) {
280 managedVersions = ArtifactUtils.copyArtifacts(managedVersions, new LinkedHashMap<>());
281 }
282 return new ResolutionGroup(
283 pomArtifact, relocatedArtifact, artifacts, managedVersions, cacheRecord.getRemoteRepositories());
284 }
285
286 cache.remove(cacheKey);
287
288 return null;
289 }
290
291 public void put(
292 Artifact artifact,
293 boolean resolveManagedVersions,
294 ArtifactRepository localRepository,
295 List<ArtifactRepository> remoteRepositories,
296 ResolutionGroup result) {
297 put(newCacheKey(artifact, resolveManagedVersions, localRepository, remoteRepositories), result);
298 }
299
300 protected CacheKey newCacheKey(
301 Artifact artifact,
302 boolean resolveManagedVersions,
303 ArtifactRepository localRepository,
304 List<ArtifactRepository> remoteRepositories) {
305 return new CacheKey(artifact, resolveManagedVersions, localRepository, remoteRepositories);
306 }
307
308 protected void put(CacheKey cacheKey, ResolutionGroup result) {
309 CacheRecord cacheRecord = new CacheRecord(
310 result.getPomArtifact(),
311 result.getRelocatedArtifact(),
312 result.getArtifacts(),
313 result.getManagedVersions(),
314 result.getResolutionRepositories());
315
316 cache.put(cacheKey, cacheRecord);
317 }
318
319 public void flush() {
320 cache.clear();
321 }
322 }