All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.webstersmalley.tv.comms.CachingComms Maven / Gradle / Ivy

/*
 * Copyright 2013 Webster Smalley
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.webstersmalley.tv.comms;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;

@Repository("cachingComms")
public class CachingComms implements Comms {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    private Comms targetComms;
    private String cacheFolder;
    private long validationTimeout;

    public void setTargetComms(Comms targetComms) {
        this.targetComms = targetComms;
    }

    public void setCacheFolder(String cacheFolder) {
        this.cacheFolder = cacheFolder;
    }

    public void setValidationTimeout(long validationTimeout) {
        this.validationTimeout = validationTimeout;
    }

    protected void createFolderIfNeeded() {
        File f = new File(cacheFolder);
        if (f.exists()) {
            if (!f.isDirectory()) {
                throw new RuntimeException("Cache folder " + cacheFolder + " exists, but is not a directory");
            }
        } else {
            if (!f.mkdirs()) {
                throw new RuntimeException("Couldn't write to folder: " + cacheFolder);
            }
        }
    }

    protected long getAgeOfFile(String filename) throws IOException {
        File f = new File(cacheFolder + "/" + filename);
        if (!f.exists()) {
            return Long.MAX_VALUE;
        }
        Path p = FileSystems.getDefault().getPath(cacheFolder, filename);

        BasicFileAttributes attributes =
                Files.readAttributes(p, BasicFileAttributes.class);
        FileTime creationTime = attributes.lastModifiedTime();

        return (System.currentTimeMillis() - creationTime.toMillis()) / 1000;
    }

    public String getURLAsString(String resource) {
        try {
            String cacheFilename = DigestUtils.md5Hex(resource);
            String contents;
            long age = getAgeOfFile(cacheFilename);
            if (age > validationTimeout) {
                logger.debug("serving: {} from target comms", resource);

                contents = targetComms.getURLAsString(resource);
                createFolderIfNeeded();
                FileOutputStream fos = new FileOutputStream(cacheFolder + "/" + cacheFilename);
                IOUtils.write(contents, fos);
                fos.flush();
                fos.close();
            } else {
                logger.debug("serving: {} from cache ({})", resource, cacheFilename);
                FileInputStream fis = new FileInputStream(cacheFolder + "/" + cacheFilename);
                contents = IOUtils.toString(fis);
                fis.close();
            }

            return contents;
        } catch (IOException e) {
            logger.error("Error getting url: " + e.getMessage(), e);
            throw new RuntimeException("Error getting url: " + e.getMessage(), e);
        }
    }

    @Override
    public String getResourceByRawHttp(URL url, String request) {
        try {
            String cacheFilename = DigestUtils.md5Hex(url.toExternalForm() + request);
            String contents;
            long age = getAgeOfFile(cacheFilename);
            if (age > validationTimeout) {
                logger.debug("serving: {} from target comms (will write to cache file: {})", url, cacheFilename);

                contents = targetComms.getResourceByRawHttp(url, request);
                createFolderIfNeeded();
                OutputStream fos = new BufferedOutputStream(new FileOutputStream(cacheFolder + "/" + cacheFilename));
                IOUtils.write(contents, fos);
                fos.flush();
                fos.close();
            } else {
                logger.debug("serving: {} from cache ({})", url, cacheFilename);
                FileInputStream fis = new FileInputStream(cacheFolder + "/" + cacheFilename);
                contents = IOUtils.toString(fis);
                fis.close();
            }

            return contents;
        } catch (IOException e) {
            logger.error("Error getting url: " + e.getMessage(), e);
            throw new RuntimeException("Error getting url: " + e.getMessage(), e);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy