1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.impl.cache;
20
21 import java.util.Map;
22 import java.util.Objects;
23 import java.util.concurrent.ConcurrentHashMap;
24 import java.util.concurrent.ConcurrentMap;
25 import java.util.function.Function;
26
27 import org.apache.maven.api.Session;
28 import org.apache.maven.api.SessionData;
29 import org.apache.maven.api.cache.CacheMetadata;
30 import org.apache.maven.api.cache.CacheRetention;
31 import org.apache.maven.api.services.Request;
32 import org.apache.maven.api.services.RequestTrace;
33 import org.apache.maven.api.services.Result;
34
35 public class DefaultRequestCache extends AbstractRequestCache {
36
37 protected static final SessionData.Key<ConcurrentMap> KEY =
38 SessionData.key(ConcurrentMap.class, CacheMetadata.class);
39 protected static final Object ROOT = new Object();
40
41 protected final Map<Object, CachingSupplier<?, ?>> forever = new ConcurrentHashMap<>();
42
43 @SuppressWarnings("unchecked")
44 protected <REQ extends Request<?>, REP extends Result<REQ>> CachingSupplier<REQ, REP> doCache(
45 REQ req, Function<REQ, REP> supplier) {
46 CacheRetention retention = Objects.requireNonNullElse(
47 req instanceof CacheMetadata metadata ? metadata.getCacheRetention() : null,
48 CacheRetention.SESSION_SCOPED);
49
50 Map<Object, CachingSupplier<?, ?>> cache = null;
51 if ((retention == CacheRetention.REQUEST_SCOPED || retention == CacheRetention.SESSION_SCOPED)
52 && req.getSession() instanceof Session session) {
53 Object key = retention == CacheRetention.REQUEST_SCOPED ? doGetOuterRequest(req) : ROOT;
54 Map<Object, Map<Object, CachingSupplier<?, ?>>> caches =
55 session.getData().computeIfAbsent(KEY, ConcurrentHashMap::new);
56 cache = caches.computeIfAbsent(key, k -> new SoftIdentityMap<>());
57 } else if (retention == CacheRetention.PERSISTENT) {
58 cache = forever;
59 }
60 if (cache != null) {
61 return (CachingSupplier<REQ, REP>) cache.computeIfAbsent(req, r -> new CachingSupplier<>(supplier));
62 } else {
63 return new CachingSupplier<>(supplier);
64 }
65 }
66
67 private <REQ extends Request<?>> Object doGetOuterRequest(REQ req) {
68 RequestTrace trace = req.getTrace();
69 while (trace != null && trace.parent() != null) {
70 trace = trace.parent();
71 }
72 return trace != null && trace.data() != null ? trace.data() : req;
73 }
74 }