• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ben-manes / caffeine / #5707

02 Aug 2026 12:45AM UTC coverage: 0.106% (-99.9%) from 100.0%
#5707

push

github

ben-manes
fix wikibench trace reader after overly strict audit fixes

0 of 4235 branches covered (0.0%)

9 of 8528 relevant lines covered (0.11%)

0.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/jcache/src/main/java/com/github/benmanes/caffeine/jcache/integration/JCacheLoaderAdapter.java
1
/*
2
 * Copyright 2015 Ben Manes. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package com.github.benmanes.caffeine.jcache.integration;
17

18
import static java.util.Objects.requireNonNull;
19

20
import java.lang.System.Logger;
21
import java.lang.System.Logger.Level;
22
import java.util.HashMap;
23
import java.util.Map;
24
import java.util.Set;
25
import java.util.concurrent.TimeUnit;
26

27
import javax.cache.CacheManager;
28
import javax.cache.expiry.Duration;
29
import javax.cache.expiry.ExpiryPolicy;
30
import javax.cache.integration.CacheLoader;
31
import javax.cache.integration.CacheLoaderException;
32

33
import org.jspecify.annotations.Nullable;
34

35
import com.github.benmanes.caffeine.cache.Ticker;
36
import com.github.benmanes.caffeine.jcache.CacheProxy;
37
import com.github.benmanes.caffeine.jcache.Expirable;
38
import com.github.benmanes.caffeine.jcache.copy.Copier;
39
import com.github.benmanes.caffeine.jcache.event.EventDispatcher;
40
import com.github.benmanes.caffeine.jcache.management.JCacheStatisticsMXBean;
41
import com.google.errorprone.annotations.Var;
42

43
/**
44
 * An adapter from a JCache cache loader to Caffeine's.
45
 *
46
 * @author ben.manes@gmail.com (Ben Manes)
47
 */
48
public final class JCacheLoaderAdapter<K, V>
49
    implements com.github.benmanes.caffeine.cache.CacheLoader<K, @Nullable Expirable<V>> {
50
  private static final Logger logger = System.getLogger(JCacheLoaderAdapter.class.getName());
×
51

52
  private final JCacheStatisticsMXBean statistics;
53
  private final EventDispatcher<K, V> dispatcher;
54
  private final CacheLoader<K, V> delegate;
55
  private final CacheManager cacheManager;
56
  private final ExpiryPolicy expiry;
57
  private final Copier copier;
58
  private final Ticker ticker;
59

60
  private @Nullable CacheProxy<K, V> cache;
61

62
  public JCacheLoaderAdapter(CacheManager cacheManager, CacheLoader<K, V> delegate,
63
      EventDispatcher<K, V> dispatcher, ExpiryPolicy expiry, Ticker ticker,
64
      JCacheStatisticsMXBean statistics, Copier copier) {
×
65
    this.cacheManager = requireNonNull(cacheManager);
×
66
    this.dispatcher = requireNonNull(dispatcher);
×
67
    this.statistics = requireNonNull(statistics);
×
68
    this.delegate = requireNonNull(delegate);
×
69
    this.copier = requireNonNull(copier);
×
70
    this.expiry = requireNonNull(expiry);
×
71
    this.ticker = requireNonNull(ticker);
×
72
  }
×
73

74
  /**
75
   * Sets the cache instance that was created with this loader.
76
   *
77
   * @param cache the cache that uses this loader
78
   */
79
  public void setCache(CacheProxy<K, V> cache) {
80
    this.cache = requireNonNull(cache);
×
81
  }
×
82

83
  @Override
84
  @SuppressWarnings("ConstantValue")
85
  public @Nullable Expirable<V> load(K key) {
86
    try {
87
      boolean statsEnabled = statistics.isEnabled();
×
88
      long start = statsEnabled ? ticker.read() : 0L;
×
89

90
      V value = delegate.load(key);
×
91
      @Var Expirable<V> expirable = null;
×
92
      if (value != null) {
×
93
        requireNonNull(cache);
×
94
        V copy = copyOf(value);
×
95
        long expireTime = expireTimeMillis(/* created= */ true);
×
96
        if (expireTime == 0L) {
×
97
          dispatcher.publishExpired(cache, key, copy);
×
98
        } else {
99
          expirable = new Expirable<>(copy, expireTime);
×
100
          dispatcher.publishCreated(cache, key, copy);
×
101
        }
102
      }
103

104
      if (statsEnabled) {
×
105
        statistics.recordGetTime(start - ticker.read());
×
106
      }
107
      return expirable;
×
108
    } catch (CacheLoaderException e) {
×
109
      throw e;
×
110
    } catch (RuntimeException e) {
×
111
      throw new CacheLoaderException(e);
×
112
    }
113
  }
114

115
  @Override
116
  public Map<K, Expirable<V>> loadAll(Set<? extends K> keys) {
117
    try {
118
      boolean statsEnabled = statistics.isEnabled();
×
119
      long start = statsEnabled ? ticker.read() : 0L;
×
120
      requireNonNull(cache);
×
121

122
      @SuppressWarnings("ConstantValue")
123
      Map<K, V> loaded = delegate.loadAll(keys);
×
124
      var result = new HashMap<K, Expirable<V>>(loaded.size());
×
125
      for (var entry : loaded.entrySet()) {
×
126
        K key = entry.getKey();
×
127
        V value = entry.getValue();
×
128
        if ((key == null) || (value == null)) {
×
129
          continue;
×
130
        }
131
        V copy = copyOf(value);
×
132
        long expireTime = expireTimeMillis(/* created= */ true);
×
133
        if (expireTime == 0L) {
×
134
          dispatcher.publishExpired(cache, key, copy);
×
135
        } else {
136
          result.put(key, new Expirable<>(copy, expireTime));
×
137
        }
138
      }
×
139
      for (var entry : result.entrySet()) {
×
140
        dispatcher.publishCreated(cache, entry.getKey(), entry.getValue().get());
×
141
      }
×
142

143
      if (statsEnabled) {
×
144
        statistics.recordGetTime(start - ticker.read());
×
145
      }
146
      return result;
×
147
    } catch (CacheLoaderException e) {
×
148
      throw e;
×
149
    } catch (RuntimeException e) {
×
150
      throw new CacheLoaderException(e);
×
151
    }
152
  }
153

154
  @Override
155
  public @Nullable Expirable<V> reload(K key, Expirable<V> oldValue) {
156
    try {
157
      V value = delegate.load(key);
×
158
      requireNonNull(cache);
×
159
      if (value == null) {
×
160
        dispatcher.publishRemovedQuietly(cache, key, oldValue.get());
×
161
        return null;
×
162
      }
163
      V copy = copyOf(value);
×
164
      @Var long expireTime = expireTimeMillis(/* created= */ false);
×
165
      if (expireTime == Long.MIN_VALUE) {
×
166
        expireTime = oldValue.getExpireTimeMillis();
×
167
      }
168
      if (expireTime == 0L) {
×
169
        dispatcher.publishExpiredQuietly(cache, key, copy);
×
170
        return null;
×
171
      }
172
      dispatcher.publishUpdatedQuietly(cache, key, oldValue.get(), copy);
×
173
      return new Expirable<>(copy, expireTime);
×
174
    } catch (CacheLoaderException e) {
×
175
      throw e;
×
176
    } catch (RuntimeException e) {
×
177
      throw new CacheLoaderException(e);
×
178
    }
179
  }
180

181
  /** Returns a copy of the value if value-based caching is enabled. */
182
  private V copyOf(V value) {
183
    return requireNonNull(copier.copy(value, requireNonNull(cacheManager.getClassLoader())));
×
184
  }
185

186
  private long expireTimeMillis(boolean created) {
187
    try {
188
      Duration duration = created ? expiry.getExpiryForCreation() : expiry.getExpiryForUpdate();
×
189
      if (duration == null) {
×
190
        return created ? Long.MAX_VALUE : Long.MIN_VALUE;
×
191
      } else if (duration.isZero()) {
×
192
        return 0;
×
193
      } else if (duration.isEternal()) {
×
194
        return Long.MAX_VALUE;
×
195
      }
196
      long millis = TimeUnit.NANOSECONDS.toMillis(ticker.read());
×
197
      long expireTime = duration.getAdjustedTime(millis);
×
198
      return ((expireTime == 0L) || (expireTime == Long.MAX_VALUE)) ? (expireTime - 1) : expireTime;
×
199
    } catch (RuntimeException e) {
×
200
      logger.log(Level.WARNING, "Exception thrown by expiry policy", e);
×
201
      return created ? Long.MAX_VALUE : Long.MIN_VALUE;
×
202
    }
203
  }
204
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc