1 package net.pterodactylus.sone.core;
3 import static com.google.common.base.Optional.absent;
4 import static com.google.common.base.Optional.of;
5 import static com.google.common.base.Ticker.systemTicker;
6 import static java.util.concurrent.TimeUnit.NANOSECONDS;
8 import java.util.concurrent.atomic.AtomicInteger;
10 import net.pterodactylus.sone.data.Sone;
12 import com.google.common.annotations.VisibleForTesting;
13 import com.google.common.base.Objects;
14 import com.google.common.base.Optional;
15 import com.google.common.base.Ticker;
18 * Class that detects {@link Sone} modifications (as per their {@link
19 * Sone#getFingerprint() fingerprints} and determines when a modified Sone may
22 class SoneModificationDetector {
24 private final Ticker ticker;
25 private final LockableFingerprintProvider lockableFingerprintProvider;
26 private final AtomicInteger insertionDelay;
27 private Optional<Long> lastModificationTime;
28 private String lastInsertFingerprint;
29 private String lastCheckFingerprint;
31 SoneModificationDetector(LockableFingerprintProvider lockableFingerprintProvider, AtomicInteger insertionDelay) {
32 this(systemTicker(), lockableFingerprintProvider, insertionDelay);
36 SoneModificationDetector(Ticker ticker, LockableFingerprintProvider lockableFingerprintProvider, AtomicInteger insertionDelay) {
38 this.lockableFingerprintProvider = lockableFingerprintProvider;
39 this.insertionDelay = insertionDelay;
40 lastCheckFingerprint = lastInsertFingerprint;
43 public boolean isEligibleForInsert() {
44 if (lockableFingerprintProvider.isLocked()) {
45 lastModificationTime = absent();
46 lastCheckFingerprint = "";
49 String fingerprint = lockableFingerprintProvider.getFingerprint();
50 if (fingerprint.equals(lastInsertFingerprint)) {
51 lastModificationTime = absent();
52 lastCheckFingerprint = fingerprint;
55 if (!Objects.equal(lastCheckFingerprint, fingerprint)) {
56 lastModificationTime = of(ticker.read());
57 lastCheckFingerprint = fingerprint;
60 return insertionDelayHasPassed();
63 public String getLastInsertFingerprint() {
64 return lastInsertFingerprint;
67 public void setFingerprint(String fingerprint) {
68 lastInsertFingerprint = fingerprint;
69 lastCheckFingerprint = lastInsertFingerprint;
70 lastModificationTime = absent();
73 private boolean insertionDelayHasPassed() {
74 return NANOSECONDS.toSeconds(ticker.read() - lastModificationTime.get()) >= insertionDelay.get();
77 public boolean isModified() {
78 return !Objects.equal(lockableFingerprintProvider.getFingerprint(), lastInsertFingerprint);
82 * Provider for a fingerprint and the information if a {@link Sone} is locked. This
83 * prevents us from having to lug a Sone object around.
85 static interface LockableFingerprintProvider {
88 String getFingerprint();