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 Core core;
27 private final Sone sone;
28 private final AtomicInteger insertionDelay;
29 private Optional<Long> lastModificationTime;
30 private String originalFingerprint;
31 private String lastFingerprint;
33 SoneModificationDetector(Core core, Sone sone, AtomicInteger insertionDelay) {
34 this(systemTicker(), core, sone, insertionDelay);
38 SoneModificationDetector(Ticker ticker, Core core, Sone sone, AtomicInteger insertionDelay) {
42 this.insertionDelay = insertionDelay;
43 originalFingerprint = sone.getFingerprint();
44 lastFingerprint = originalFingerprint;
47 public boolean isEligibleForInsert() {
48 if (core.isLocked(sone)) {
49 lastModificationTime = absent();
53 String fingerprint = sone.getFingerprint();
54 if (originalFingerprint.equals(fingerprint)) {
55 lastModificationTime = absent();
56 lastFingerprint = fingerprint;
59 if (!lastFingerprint.equals(fingerprint)) {
60 lastModificationTime = of(ticker.read());
61 lastFingerprint = fingerprint;
64 return insertionDelayHasPassed();
67 public String getOriginalFingerprint() {
68 return originalFingerprint;
71 public void setFingerprint(String fingerprint) {
72 originalFingerprint = fingerprint;
73 lastFingerprint = originalFingerprint;
74 lastModificationTime = absent();
77 private boolean insertionDelayHasPassed() {
78 return lastModificationTime.isPresent() && (NANOSECONDS.toSeconds(ticker.read() - lastModificationTime.get()) >= insertionDelay.get());
81 public boolean isModified() {
82 return !sone.getFingerprint().equals(originalFingerprint);