mirror of https://github.com/micromata/borgbackup-butler.git

Kai Reinhard
09.27.2018 6ab55d3f236c98b4381cc8b37057e684aa522e7f
Caches...
1 files added
6 files modified
174 ■■■■■ changed files
borgbutler-core/src/main/java/de/micromata/borgbutler/cache/AbstractCache.java 60 ●●●● patch | view | raw | blame | history
borgbutler-core/src/main/java/de/micromata/borgbutler/cache/AbstractElementsCache.java 76 ●●●●● patch | view | raw | blame | history
borgbutler-core/src/main/java/de/micromata/borgbutler/cache/ArchiveListCache.java 2 ●●● patch | view | raw | blame | history
borgbutler-core/src/main/java/de/micromata/borgbutler/cache/ButlerCache.java 16 ●●●● patch | view | raw | blame | history
borgbutler-core/src/main/java/de/micromata/borgbutler/cache/RepoInfoCache.java 2 ●●● patch | view | raw | blame | history
borgbutler-core/src/main/java/de/micromata/borgbutler/cache/RepoListCache.java 2 ●●● patch | view | raw | blame | history
borgbutler-core/src/main/java/de/micromata/borgbutler/config/ConfigurationHandler.java 16 ●●●● patch | view | raw | blame | history
borgbutler-core/src/main/java/de/micromata/borgbutler/cache/AbstractCache.java
@@ -1,7 +1,6 @@
package de.micromata.borgbutler.cache;
import com.fasterxml.jackson.annotation.JsonIgnore;
import de.micromata.borgbutler.config.BorgRepoConfig;
import de.micromata.borgbutler.config.Definitions;
import de.micromata.borgbutler.json.JsonUtils;
import lombok.Getter;
@@ -15,73 +14,40 @@
import java.io.*;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public abstract class AbstractCache<T> {
public abstract class AbstractCache {
    private static Logger log = LoggerFactory.getLogger(AbstractCache.class);
    private static final String CACHE_FILE_PREFIX = "cache-";
    private static final String CACHE_FILE_EXTENSION = "json";
    private static final String CACHE_FILE_ZIP_EXTENSION = ".zip";
    private static final String CACHE_FILE_ZIP_EXTENSION = ".gz";
    /**
     * INITIAL - on startup (not yet read), DIRTY - modifications not written, SAVED - content written to file.
     */
    private enum STATE {INITIAL, DIRTY, SAVED}
    protected enum STATE {INITIAL, DIRTY, SAVED}
    @JsonIgnore
    protected File cacheFile;
    @JsonIgnore
    @Getter
    private boolean zip;
    private boolean compress;
    @Getter
    @JsonIgnore
    private STATE state = STATE.INITIAL;
    @Getter
    private Date lastModified;
    @Getter
    private Date created;
    @Getter
    protected Map<String, T> elements = new HashMap<>();
    public T get(BorgRepoConfig repoConfig, String identifier) {
        if (identifier == null) {
            return null;
        }
        if (this.state == STATE.INITIAL) {
            read();
        }
        for (T element : elements.values()) {
            if (matches(element, identifier)) {
                return element;
            }
        }
        return load(repoConfig, identifier);
    }
    protected abstract T load(BorgRepoConfig repoConfig, String identifier);
    public abstract boolean matches(T element, String identifier);
    public abstract String getIdentifier(T element);
    public abstract void updateFrom(T dest, T source);
    /**
     * Removes all entries (doesn't effect the cache files!).
     */
    public void clear() {
        elements.clear();
        state = STATE.DIRTY;
    }
    public void upsert(BorgRepoConfig repoConfig, T element) {
        T existingElement = get(repoConfig, getIdentifier(element));
        if (existingElement == null) {
            elements.put(getIdentifier(element), element);
        } else {
            updateFrom(existingElement, element);
        }
        state = STATE.DIRTY; // Needed to save cache to file.
    protected void setDirty() {
        state = STATE.DIRTY;
    }
    public void read() {
@@ -93,7 +59,7 @@
            }
            log.info("Parsing cache file '" + cacheFile.getAbsolutePath() + "'.");
            String json;
            if (zip) {
            if (compress) {
                try (GzipCompressorInputStream in = new GzipCompressorInputStream(new FileInputStream(cacheFile))) {
                    StringWriter writer = new StringWriter();
                    IOUtils.copy(in, writer, Definitions.STD_CHARSET);
@@ -104,10 +70,10 @@
            }
            AbstractCache readCache = JsonUtils.fromJson(this.getClass(), json);
            if (readCache != null) {
                this.elements = readCache.elements;
                this.lastModified = readCache.lastModified;
                this.created = readCache.created;
                this.state = STATE.SAVED; // State of cache is updated from cache file.
                update(readCache);
            } else {
                log.error("Error while parsing cache: " + cacheFile.getAbsolutePath());
                this.state = STATE.DIRTY; // Needed to save cache to file.
@@ -119,6 +85,8 @@
        }
    }
    protected abstract void update(AbstractCache readCache);
    public void save() {
        if (this.state == STATE.SAVED || this.state == STATE.INITIAL) {
            log.info("Cache file is up to date (nothing to save): " + cacheFile);
@@ -132,7 +100,7 @@
        }
        String json = JsonUtils.toJson(this);
        try {
            if (this.zip) {
            if (this.compress) {
                try (GzipCompressorOutputStream out = new GzipCompressorOutputStream(new FileOutputStream(cacheFile))) {
                    IOUtils.copy(new StringReader(json), out, Definitions.STD_CHARSET);
                }
@@ -158,9 +126,9 @@
    }
    AbstractCache(File cacheDir, String cacheFilename, boolean zip) {
        this.zip = zip;
        this.compress = zip;
        String filename = CACHE_FILE_PREFIX + cacheFilename + "." + CACHE_FILE_EXTENSION;
        if (this.zip)
        if (this.compress)
            filename = filename + CACHE_FILE_EXTENSION;
        cacheFile = new File(cacheDir, CACHE_FILE_PREFIX + cacheFilename + "." + CACHE_FILE_EXTENSION);
        this.state = STATE.INITIAL;
borgbutler-core/src/main/java/de/micromata/borgbutler/cache/AbstractElementsCache.java
New file
@@ -0,0 +1,76 @@
package de.micromata.borgbutler.cache;
import de.micromata.borgbutler.config.BorgRepoConfig;
import lombok.Getter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
public abstract class AbstractElementsCache<T> extends AbstractCache {
    private static Logger log = LoggerFactory.getLogger(AbstractElementsCache.class);
    @Getter
    protected Map<String, T> elements = new HashMap<>();
    public T get(BorgRepoConfig repoConfig, String identifier) {
        if (identifier == null) {
            return null;
        }
        if (getState() == STATE.INITIAL) {
            read();
        }
        for (T element : elements.values()) {
            if (matches(element, identifier)) {
                return element;
            }
        }
        return load(repoConfig, identifier);
    }
    protected abstract T load(BorgRepoConfig repoConfig, String identifier);
    public abstract boolean matches(T element, String identifier);
    public abstract String getIdentifier(T element);
    public abstract void updateFrom(T dest, T source);
    /**
     * Removes all entries (doesn't effect the cache files!).
     */
    public void clear() {
        elements.clear();
        super.clear();
    }
    public void upsert(BorgRepoConfig repoConfig, T element) {
        T existingElement = get(repoConfig, getIdentifier(element));
        if (existingElement == null) {
            elements.put(getIdentifier(element), element);
        } else {
            updateFrom(existingElement, element);
        }
        setDirty();
    }
    protected void update(AbstractCache readCache) {
        this.elements = ((AbstractElementsCache)readCache).elements;
    }
    /**
     * Needed by jackson for deserialization.
     */
    AbstractElementsCache() {
    }
    AbstractElementsCache(File cacheDir, String cacheFilename) {
        super(cacheDir, cacheFilename);
    }
    AbstractElementsCache(File cacheDir, String cacheFilename, boolean compress) {
        super(cacheDir, cacheFilename, compress);
    }
}
borgbutler-core/src/main/java/de/micromata/borgbutler/cache/ArchiveListCache.java
@@ -8,7 +8,7 @@
import java.io.File;
public class ArchiveListCache extends AbstractCache<ArchiveInfo> {
public class ArchiveListCache extends AbstractElementsCache<ArchiveInfo> {
    private static Logger log = LoggerFactory.getLogger(ArchiveListCache.class);
    public static final String CACHE_ARCHIVE_LISTS_BASENAME = "archive-lists";
borgbutler-core/src/main/java/de/micromata/borgbutler/cache/ButlerCache.java
@@ -1,6 +1,7 @@
package de.micromata.borgbutler.cache;
import com.fasterxml.jackson.annotation.JsonIgnore;
import de.micromata.borgbutler.config.ConfigurationHandler;
import lombok.Getter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -11,7 +12,7 @@
public class ButlerCache {
    private static Logger log = LoggerFactory.getLogger(ButlerCache.class);
    public static final String CACHE_DIR_NAME = ".borgbutler";
    public static final String CACHE_DIR_NAME = "caches";
    private static ButlerCache instance = new ButlerCache();
    @Getter
@@ -19,7 +20,7 @@
    @Getter
    private RepoListCache repoListCache;
    private ArchiveListCache archiveListCache;
    private List<AbstractCache> caches;
    private List<AbstractElementsCache> caches;
    @JsonIgnore
    private File cacheDir;
@@ -29,13 +30,13 @@
    }
    public void read() {
        for (AbstractCache cache : caches) {
        for (AbstractElementsCache cache : caches) {
            cache.read();
        }
    }
    public void save() {
        for (AbstractCache cache : caches) {
        for (AbstractElementsCache cache : caches) {
            cache.save();
        }
    }
@@ -46,19 +47,18 @@
    public void removeAllCacheFiles() {
        File[] files = cacheDir.listFiles();
        for (File file : files) {
            if (AbstractCache.isCacheFile(file)) {
            if (AbstractElementsCache.isCacheFile(file)) {
                log.info("Deleting cache file: " + file.getAbsolutePath());
                file.delete();
            }
        }
        for (AbstractCache cache : caches) {
        for (AbstractElementsCache cache : caches) {
            cache.clear();
        }
    }
    private ButlerCache() {
        String homeDir = System.getProperty("user.home");
        cacheDir = new File(homeDir, CACHE_DIR_NAME);
        cacheDir = new File(ConfigurationHandler.getInstance().getWorkingDir(), CACHE_DIR_NAME);
        if (!cacheDir.exists()) {
            log.info("Creating cache dir: " + cacheDir.getAbsolutePath());
            cacheDir.mkdir();
borgbutler-core/src/main/java/de/micromata/borgbutler/cache/RepoInfoCache.java
@@ -8,7 +8,7 @@
import java.io.File;
public class RepoInfoCache extends AbstractCache<RepoInfo> {
public class RepoInfoCache extends AbstractElementsCache<RepoInfo> {
    private static Logger log = LoggerFactory.getLogger(RepoInfoCache.class);
    public static final String CACHE_REPOS_BASENAME = "repo-infos";
borgbutler-core/src/main/java/de/micromata/borgbutler/cache/RepoListCache.java
@@ -8,7 +8,7 @@
import java.io.File;
public class RepoListCache extends AbstractCache<RepoList> {
public class RepoListCache extends AbstractElementsCache<RepoList> {
    private static Logger log = LoggerFactory.getLogger(RepoListCache.class);
    public static final String CACHE_REPO_LISTS_BASENAME = "repo-lists";
borgbutler-core/src/main/java/de/micromata/borgbutler/config/ConfigurationHandler.java
@@ -12,11 +12,13 @@
public class ConfigurationHandler {
    private static Logger log = LoggerFactory.getLogger(ConfigurationHandler.class);
    private static ConfigurationHandler instance = new ConfigurationHandler();
    private static final String APP_WORKING_DIR = ".borgbutler";
    private static final String CONFIG_FILENAME = ".borgbutler.json";
    private static final String CONFIG_BACKUP_FILENAME = ".borgbutler-bak.json";
    @Getter
    private File configFile;
    private File backupConfigFile;
    private File workingDir;
    private Configuration configuration = new Configuration();
    public static ConfigurationHandler getInstance() {
@@ -53,8 +55,18 @@
        }
    }
    public File getWorkingDir() {
        if (!workingDir.exists()) {
            log.info("Creating borg-butlers working directory: " + workingDir.getAbsolutePath());
            workingDir.mkdirs();
        }
        return workingDir;
    }
    private ConfigurationHandler() {
        configFile = new File(System.getProperty("user.home"), CONFIG_FILENAME);
        backupConfigFile = new File(System.getProperty("user.home"), CONFIG_BACKUP_FILENAME);
        File userHome = new File(System.getProperty("user.home"));
        configFile = new File(userHome, CONFIG_FILENAME);
        backupConfigFile = new File(userHome, CONFIG_BACKUP_FILENAME);
        workingDir = new File(userHome, APP_WORKING_DIR);
    }
}