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.Optional;
14 import com.google.common.base.Ticker;
17 * Class that detects {@link Sone} modifications (as per their {@link
18 * Sone#getFingerprint() fingerprints} and determines when a modified Sone may
21 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
23 class SoneModificationDetector {
25 private final Ticker ticker;
26 private final LockableFingerprintProvider lockableFingerprintProvider;
27 private final AtomicInteger insertionDelay;
28 private Optional<Long> lastModificationTime;
29 private String originalFingerprint;
30 private String lastFingerprint;
32 SoneModificationDetector(LockableFingerprintProvider lockableFingerprintProvider, AtomicInteger insertionDelay) {
33 this(systemTicker(), lockableFingerprintProvider, insertionDelay);
37 SoneModificationDetector(Ticker ticker, LockableFingerprintProvider lockableFingerprintProvider, AtomicInteger insertionDelay) {
39 this.lockableFingerprintProvider = lockableFingerprintProvider;
40 this.insertionDelay = insertionDelay;
41 lastFingerprint = originalFingerprint;
44 public boolean isEligibleForInsert() {
45 if (lockableFingerprintProvider.isLocked()) {
46 lastModificationTime = absent();
50 String fingerprint = lockableFingerprintProvider.getFingerprint();
51 if (originalFingerprint.equals(fingerprint)) {
52 lastModificationTime = absent();
53 lastFingerprint = fingerprint;
56 if (!lastFingerprint.equals(fingerprint)) {
57 lastModificationTime = of(ticker.read());
58 lastFingerprint = fingerprint;
61 return insertionDelayHasPassed();
64 public String getOriginalFingerprint() {
65 return originalFingerprint;
68 public void setFingerprint(String fingerprint) {
69 originalFingerprint = fingerprint;
70 lastFingerprint = originalFingerprint;
71 lastModificationTime = absent();
74 private boolean insertionDelayHasPassed() {
75 return NANOSECONDS.toSeconds(ticker.read() - lastModificationTime.get()) >= insertionDelay.get();
78 public boolean isModified() {
79 return !lockableFingerprintProvider.getFingerprint().equals(originalFingerprint);
83 * Provider for a fingerprint and the information if a {@link Sone} is locked. This
84 * prevents us from having to lug a Sone object around.
86 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
88 static interface LockableFingerprintProvider {
91 String getFingerprint();