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 @Override
44 @SuppressWarnings("unchecked")
45 protected <REQ extends Request<?>, REP extends Result<REQ>> CachingSupplier<REQ, REP> doCache(
46 REQ req, Function<REQ, REP> supplier) {
47 CacheRetention retention = Objects.requireNonNullElse(
48 req instanceof CacheMetadata metadata ? metadata.getCacheRetention() : null,
49 CacheRetention.SESSION_SCOPED);
50
51 Map<Object, CachingSupplier<?, ?>> cache = null;
52 if ((retention == CacheRetention.REQUEST_SCOPED || retention == CacheRetention.SESSION_SCOPED)
53 && req.getSession() instanceof Session session) {
54 Object key = retention == CacheRetention.REQUEST_SCOPED ? doGetOuterRequest(req) : ROOT;
55 Map<Object, Map<Object, CachingSupplier<?, ?>>> caches =
56 session.getData().computeIfAbsent(KEY, ConcurrentHashMap::new);
57 cache = caches.computeIfAbsent(key, k -> new SoftIdentityMap<>());
58 } else if (retention == CacheRetention.PERSISTENT) {
59 cache = forever;
60 }
61 if (cache != null) {
62 return (CachingSupplier<REQ, REP>) cache.computeIfAbsent(req, r -> new CachingSupplier<>(supplier));
63 } else {
64 return new CachingSupplier<>(supplier);
65 }
66 }
67
68 private <REQ extends Request<?>> Object doGetOuterRequest(REQ req) {
69 RequestTrace trace = req.getTrace();
70 while (trace != null && trace.parent() != null) {
71 trace = trace.parent();
72 }
73 return trace != null && trace.data() != null ? trace.data() : req;
74 }
75 }