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)) {
96 return false;
97 }
98
99 CacheKey other = (CacheKey) o;
100
101 return pomHash == other.pomHash
102 && artifactEquals(artifact, other.artifact)
103 && resolveManagedVersions == other.resolveManagedVersions
104 && repositoriesEquals(repositories, other.repositories);
105 }
106 }
107
108 private static int artifactHashCode(Artifact a) {
109 int result = 17;
110 result = 31 * result + a.getGroupId().hashCode();
111 result = 31 * result + a.getArtifactId().hashCode();
112 result = 31 * result + a.getType().hashCode();
113 if (a.getVersion() != null) {
114 result = 31 * result + a.getVersion().hashCode();
115 }
116 result = 31 * result + (a.getClassifier() != null ? a.getClassifier().hashCode() : 0);
117 result = 31 * result + (a.getScope() != null ? a.getScope().hashCode() : 0);
118 result = 31 * result
119 + (a.getDependencyFilter() != null ? a.getDependencyFilter().hashCode() : 0);
120 result = 31 * result + (a.isOptional() ? 1 : 0);
121 return result;
122 }
123
124 private static boolean artifactEquals(Artifact a1, Artifact a2) {
125 if (a1 == a2) {
126 return true;
127 }
128
129 return Objects.equals(a1.getGroupId(), a2.getGroupId())
130 && Objects.equals(a1.getArtifactId(), a2.getArtifactId())
131 && Objects.equals(a1.getType(), a2.getType())
132 && Objects.equals(a1.getVersion(), a2.getVersion())
133 && Objects.equals(a1.getClassifier(), a2.getClassifier())
134 && Objects.equals(a1.getScope(), a2.getScope())
135 && Objects.equals(a1.getDependencyFilter(), a2.getDependencyFilter())
136 && a1.isOptional() == a2.isOptional();
137 }
138
139 private static int repositoryHashCode(ArtifactRepository repository) {
140 int result = 17;
141 result = 31 * result + (repository.getId() != null ? repository.getId().hashCode() : 0);
142 return result;
143 }
144
145 private static int repositoriesHashCode(List<ArtifactRepository> repositories) {
146 int result = 17;
147 for (ArtifactRepository repository : repositories) {
148 result = 31 * result + repositoryHashCode(repository);
149 }
150 return result;
151 }
152
153 private static boolean repositoryEquals(ArtifactRepository r1, ArtifactRepository r2) {
154 if (r1 == r2) {
155 return true;
156 }
157
158 return Objects.equals(r1.getId(), r2.getId())
159 && Objects.equals(r1.getUrl(), r2.getUrl())
160 && repositoryPolicyEquals(r1.getReleases(), r2.getReleases())
161 && repositoryPolicyEquals(r1.getSnapshots(), r2.getSnapshots());
162 }
163
164 private static boolean repositoryPolicyEquals(ArtifactRepositoryPolicy p1, ArtifactRepositoryPolicy p2) {
165 if (p1 == p2) {
166 return true;
167 }
168
169 return p1.isEnabled() == p2.isEnabled() && Objects.equals(p1.getUpdatePolicy(), p2.getUpdatePolicy());
170 }
171
172 private static boolean repositoriesEquals(List<ArtifactRepository> r1, List<ArtifactRepository> r2) {
173 if (r1.size() != r2.size()) {
174 return false;
175 }
176
177 for (Iterator<ArtifactRepository> it1 = r1.iterator(), it2 = r2.iterator(); it1.hasNext(); ) {
178 if (!repositoryEquals(it1.next(), it2.next())) {
179 return false;
180 }
181 }
182
183 return true;
184 }
185
186
187
188
189 public class CacheRecord {
190 private Artifact pomArtifact;
191 private Artifact relocatedArtifact;
192 private List<Artifact> artifacts;
193 private Map<String, Artifact> managedVersions;
194 private List<ArtifactRepository> remoteRepositories;
195
196 private long length;
197 private long timestamp;
198
199 CacheRecord(
200 Artifact pomArtifact,
201 Artifact relocatedArtifact,
202 Set<Artifact> artifacts,
203 Map<String, Artifact> managedVersions,
204 List<ArtifactRepository> remoteRepositories) {
205 this.pomArtifact = ArtifactUtils.copyArtifact(pomArtifact);
206 this.relocatedArtifact = ArtifactUtils.copyArtifactSafe(relocatedArtifact);
207 this.artifacts = ArtifactUtils.copyArtifacts(artifacts, new ArrayList<>());
208 this.remoteRepositories = new ArrayList<>(remoteRepositories);
209
210 this.managedVersions = managedVersions;
211 if (managedVersions != null) {
212 this.managedVersions = ArtifactUtils.copyArtifacts(managedVersions, new LinkedHashMap<>());
213 }
214
215 File pomFile = pomArtifact.getFile();
216 if (pomFile != null && pomFile.canRead()) {
217 this.length = pomFile.length();
218 this.timestamp = pomFile.lastModified();
219 } else {
220 this.length = -1;
221 this.timestamp = -1;
222 }
223 }
224
225 public Artifact getArtifact() {
226 return pomArtifact;
227 }
228
229 public Artifact getRelocatedArtifact() {
230 return relocatedArtifact;
231 }
232
233 public List<Artifact> getArtifacts() {
234 return artifacts;
235 }
236
237 public Map<String, Artifact> getManagedVersions() {
238 return managedVersions;
239 }
240
241 public List<ArtifactRepository> getRemoteRepositories() {
242 return remoteRepositories;
243 }
244
245 public boolean isStale() {
246 File pomFile = pomArtifact.getFile();
247 if (pomFile != null) {
248 if (pomFile.canRead()) {
249 return length != pomFile.length() || timestamp != pomFile.lastModified();
250 } else {
251
252 boolean snapshot = pomArtifact.isSnapshot();
253 for (ArtifactRepository repository : remoteRepositories) {
254 ArtifactRepositoryPolicy policy =
255 snapshot ? repository.getSnapshots() : repository.getReleases();
256 if (ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS.equals(policy.getUpdatePolicy())) {
257 return true;
258 }
259 }
260 }
261 }
262
263 return length != -1 || timestamp != -1;
264 }
265 }
266
267 public ResolutionGroup get(
268 Artifact artifact,
269 boolean resolveManagedVersions,
270 ArtifactRepository localRepository,
271 List<ArtifactRepository> remoteRepositories) {
272 CacheKey cacheKey = newCacheKey(artifact, resolveManagedVersions, localRepository, remoteRepositories);
273
274 CacheRecord cacheRecord = cache.get(cacheKey);
275
276 if (cacheRecord != null && !cacheRecord.isStale()) {
277 Artifact pomArtifact = ArtifactUtils.copyArtifact(cacheRecord.getArtifact());
278 Artifact relocatedArtifact = ArtifactUtils.copyArtifactSafe(cacheRecord.getRelocatedArtifact());
279 Set<Artifact> artifacts = ArtifactUtils.copyArtifacts(cacheRecord.getArtifacts(), new LinkedHashSet<>());
280 Map<String, Artifact> managedVersions = cacheRecord.getManagedVersions();
281 if (managedVersions != null) {
282 managedVersions = ArtifactUtils.copyArtifacts(managedVersions, new LinkedHashMap<>());
283 }
284 return new ResolutionGroup(
285 pomArtifact, relocatedArtifact, artifacts, managedVersions, cacheRecord.getRemoteRepositories());
286 }
287
288 cache.remove(cacheKey);
289
290 return null;
291 }
292
293 public void put(
294 Artifact artifact,
295 boolean resolveManagedVersions,
296 ArtifactRepository localRepository,
297 List<ArtifactRepository> remoteRepositories,
298 ResolutionGroup result) {
299 put(newCacheKey(artifact, resolveManagedVersions, localRepository, remoteRepositories), result);
300 }
301
302 protected CacheKey newCacheKey(
303 Artifact artifact,
304 boolean resolveManagedVersions,
305 ArtifactRepository localRepository,
306 List<ArtifactRepository> remoteRepositories) {
307 return new CacheKey(artifact, resolveManagedVersions, localRepository, remoteRepositories);
308 }
309
310 protected void put(CacheKey cacheKey, ResolutionGroup result) {
311 CacheRecord cacheRecord = new CacheRecord(
312 result.getPomArtifact(),
313 result.getRelocatedArtifact(),
314 result.getArtifacts(),
315 result.getManagedVersions(),
316 result.getResolutionRepositories());
317
318 cache.put(cacheKey, cacheRecord);
319 }
320
321 public void flush() {
322 cache.clear();
323 }
324 }