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 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
24 class SoneModificationDetector {
26 private final Ticker ticker;
27 private final LockableFingerprintProvider lockableFingerprintProvider;
28 private final AtomicInteger insertionDelay;
29 private Optional<Long> lastModificationTime;
30 private String originalFingerprint;
31 private String lastFingerprint;
33 SoneModificationDetector(LockableFingerprintProvider lockableFingerprintProvider, AtomicInteger insertionDelay) {
34 this(systemTicker(), lockableFingerprintProvider, insertionDelay);
38 SoneModificationDetector(Ticker ticker, LockableFingerprintProvider lockableFingerprintProvider, AtomicInteger insertionDelay) {
40 this.lockableFingerprintProvider = lockableFingerprintProvider;
41 this.insertionDelay = insertionDelay;
42 lastFingerprint = originalFingerprint;
45 public boolean isEligibleForInsert() {
46 if (lockableFingerprintProvider.isLocked()) {
47 lastModificationTime = absent();
51 String fingerprint = lockableFingerprintProvider.getFingerprint();
52 if (originalFingerprint.equals(fingerprint)) {
53 lastModificationTime = absent();
54 lastFingerprint = fingerprint;
57 if (!lastFingerprint.equals(fingerprint)) {
58 lastModificationTime = of(ticker.read());
59 lastFingerprint = fingerprint;
62 return insertionDelayHasPassed();
65 public String getOriginalFingerprint() {
66 return originalFingerprint;
69 public void setFingerprint(String fingerprint) {
70 originalFingerprint = fingerprint;
71 lastFingerprint = originalFingerprint;
72 lastModificationTime = absent();
75 private boolean insertionDelayHasPassed() {
76 return NANOSECONDS.toSeconds(ticker.read() - lastModificationTime.get()) >= insertionDelay.get();
79 public boolean isModified() {
80 return !Objects.equal(lockableFingerprintProvider.getFingerprint(), originalFingerprint);
84 * Provider for a fingerprint and the information if a {@link Sone} is locked. This
85 * prevents us from having to lug a Sone object around.
87 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
89 static interface LockableFingerprintProvider {
92 String getFingerprint();