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

Kai Reinhard
10.19.2018 1537fb95a9977a162dc29e2487c4020e96b43074
borgbutler-core/src/main/java/de/micromata/borgbutler/cache/AbstractCache.java
@@ -21,11 +21,6 @@
    private static final String CACHE_FILE_EXTENSION = "json";
    private static final String CACHE_FILE_ZIP_EXTENSION = ".gz";
    /**
     * INITIAL - on startup (not yet read), DIRTY - modifications not written, SAVED - content written to file.
     */
    protected enum STATE {INITIAL, DIRTY, SAVED}
    @JsonIgnore
    protected File cacheFile;
    @JsonIgnore
@@ -33,7 +28,7 @@
    private boolean compress;
    @Getter
    @JsonIgnore
    private STATE state = STATE.INITIAL;
    private CacheState state = CacheState.INITIAL;
    @Getter
    private Date lastModified;
    @Getter
@@ -43,7 +38,7 @@
     * Removes all entries (doesn't effect the cache files!).
     */
    public void clear() {
        state = STATE.DIRTY;
        state = CacheState.INITIAL;
    }
    /**
@@ -56,76 +51,94 @@
                cacheFile.delete();
            }
            clear();
            state = STATE.SAVED;
        }
    }
    protected void setDirty() {
        state = STATE.DIRTY;
        state = CacheState.DIRTY;
    }
    public void read() {
        try {
            if (!cacheFile.exists()) {
                // Cache file doesn't exist. Nothing to read.
                state = STATE.DIRTY; // Needed to save cache to file.
        if (state == CacheState.LOADING_FROM_CACHE_FILE) {
            // Already in progress, nothing to do.
            synchronized (this) {
                // Wait and do nothing.
                return;
            }
            log.info("Parsing cache file '" + cacheFile.getAbsolutePath() + "'.");
            String json;
            if (compress) {
                try (GzipCompressorInputStream in = new GzipCompressorInputStream(new FileInputStream(cacheFile))) {
                    StringWriter writer = new StringWriter();
                    IOUtils.copy(in, writer, Definitions.STD_CHARSET);
                    json = writer.toString();
        }
        synchronized (this) {
            try {
                state = CacheState.LOADING_FROM_CACHE_FILE;
                if (!cacheFile.exists()) {
                    // Cache file doesn't exist. Nothing to read.
                    state = CacheState.DIRTY; // Needed to save cache to file.
                    return;
                }
            } else {
                json = FileUtils.readFileToString(cacheFile, Definitions.STD_CHARSET);
                log.info("Parsing cache file '" + cacheFile.getAbsolutePath() + "'.");
                String json;
                if (compress) {
                    try (GzipCompressorInputStream in = new GzipCompressorInputStream(new FileInputStream(cacheFile))) {
                        StringWriter writer = new StringWriter();
                        IOUtils.copy(in, writer, Definitions.STD_CHARSET);
                        json = writer.toString();
                    }
                } else {
                    json = FileUtils.readFileToString(cacheFile, Definitions.STD_CHARSET);
                }
                AbstractCache readCache = JsonUtils.fromJson(this.getClass(), json);
                if (readCache != null) {
                    this.lastModified = readCache.lastModified;
                    this.created = readCache.created;
                    update(readCache);
                    this.state = CacheState.SAVED; // State of cache is updated from cache file.
                } else {
                    log.error("Error while parsing cache: " + cacheFile.getAbsolutePath());
                    this.state = CacheState.DIRTY; // Needed to save cache to file.
                }
            } catch (IOException ex) {
                log.error("Error while trying to read cache file '" + cacheFile.getAbsolutePath() + "': "
                        + ex.getMessage(), ex);
                this.state = CacheState.DIRTY; // Needed to save cache to file.
            }
            AbstractCache readCache = JsonUtils.fromJson(this.getClass(), json);
            if (readCache != null) {
                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.
            }
        } catch (IOException ex) {
            log.error("Error while trying to read cache file '" + cacheFile.getAbsolutePath() + "': "
                    + ex.getMessage(), ex);
            this.state = STATE.DIRTY; // Needed to save cache to file.
        }
    }
    protected abstract void update(AbstractCache readCache);
    public void save() {
        if (this.state == STATE.SAVED || this.state == STATE.INITIAL) {
        if (this.state == CacheState.SAVED || this.state == CacheState.INITIAL) {
            log.info("Cache file is up to date (nothing to save): " + cacheFile);
            return;
        }
        log.info("Saving to cache file: " + cacheFile);
        if (created == null) {
            created = lastModified = new Date();
        } else {
            lastModified = new Date();
        }
        String json = JsonUtils.toJson(this);
        try {
            if (this.compress) {
                try (GzipCompressorOutputStream out = new GzipCompressorOutputStream(new FileOutputStream(cacheFile))) {
                    IOUtils.copy(new StringReader(json), out, Definitions.STD_CHARSET);
                }
            } else {
                FileUtils.write(cacheFile, json, Definitions.STD_CHARSET);
        if (state == CacheState.SAVING) {
            // Already in progress, nothing to do.
            synchronized (this) {
                // Wait and do nothing.
                return;
            }
            this.state = STATE.SAVED;
        } catch (IOException ex) {
            log.error("Error while trying to write cache file '" + cacheFile.getAbsolutePath() + "': "
                    + ex.getMessage(), ex);
            this.state = STATE.DIRTY;
        }
        synchronized (this) {
            log.info("Saving to cache file: " + cacheFile);
            if (created == null) {
                created = lastModified = new Date();
            } else {
                lastModified = new Date();
            }
            String json = JsonUtils.toJson(this);
            try {
                if (this.compress) {
                    try (GzipCompressorOutputStream out = new GzipCompressorOutputStream(new FileOutputStream(cacheFile))) {
                        IOUtils.copy(new StringReader(json), out, Definitions.STD_CHARSET);
                    }
                } else {
                    FileUtils.write(cacheFile, json, Definitions.STD_CHARSET);
                }
                this.state = CacheState.SAVED;
            } catch (IOException ex) {
                log.error("Error while trying to write cache file '" + cacheFile.getAbsolutePath() + "': "
                        + ex.getMessage(), ex);
                this.state = CacheState.DIRTY;
            }
        }
    }
@@ -145,7 +158,7 @@
        if (this.compress)
            filename = filename + CACHE_FILE_ZIP_EXTENSION;
        cacheFile = new File(cacheDir, filename);
        this.state = STATE.INITIAL;
        this.state = CacheState.INITIAL;
    }
    public static boolean isCacheFile(File file) {