com.crushpaper.CachingResource.java Source code

Java tutorial

Introduction

Here is the source code for com.crushpaper.CachingResource.java

Source

/*
Copyright 2015 CrushPaper.com.
    
This file is part of CrushPaper.
    
CrushPaper is free software: you can redistribute it and/or modify
it under the terms of version 3 of the GNU Affero General Public
License as published by the Free Software Foundation.
    
CrushPaper is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.
    
You should have received a copy of the GNU Affero General Public License
along with CrushPaper.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.crushpaper;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.channels.ReadableByteChannel;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.io.IOUtils;
import org.eclipse.jetty.util.resource.Resource;

/** This class caches resources for the lifetime of the process. */
public class CachingResource extends Resource {
    private Resource resource;
    private byte[] cachedInput;
    private String directory;

    private static ConcurrentHashMap<String, CachingResource> cachedResources = new ConcurrentHashMap<String, CachingResource>();

    protected CachingResource(Resource resource, String directory) {
        this.resource = resource;
        this.directory = directory;
    }

    @Override
    public boolean isContainedIn(Resource r) throws MalformedURLException {
        return resource.isContainedIn(r);
    }

    @Override
    public void close() {
        resource.close();
    }

    @Override
    public boolean exists() {
        return resource.exists();
    }

    @Override
    public boolean isDirectory() {
        return resource.isDirectory();
    }

    @Override
    public long lastModified() {
        return resource.lastModified();
    }

    @Override
    public long length() {
        cache();

        return cachedInput.length;
    }

    @Override
    public URL getURL() {
        return resource.getURL();
    }

    @Override
    public File getFile() throws IOException {
        return resource.getFile();
    }

    @Override
    public String getName() {
        return resource.getName();
    }

    private void cache() {
        // In this case the input was already cached.
        if (cachedInput != null) {
            return;
        }

        try {
            cachedInput = IOUtils.toByteArray(resource.getInputStream());
        } catch (IOException e) {
        }
    }

    @Override
    public InputStream getInputStream() throws IOException {
        // The input was probably already cached by a call to length().
        cache();

        return new ByteArrayInputStream(cachedInput);
    }

    /** Never returns a readable byte channel even if the resource supports it. */
    @Override
    public ReadableByteChannel getReadableByteChannel() throws IOException {
        return null;
    }

    @Override
    public boolean delete() throws SecurityException {
        return resource.delete();
    }

    @Override
    public boolean renameTo(Resource dest) throws SecurityException {
        return resource.renameTo(dest);
    }

    @Override
    public String[] list() {
        return resource.list();
    }

    @Override
    public Resource addPath(String path) throws IOException, MalformedURLException {
        String fullPath = directory + path;

        // If it was already cached return from the cache.
        CachingResource cached = cachedResources.get(fullPath);
        if (cached != null) {
            return cached;
        }

        // Get the real underlying resource.
        Resource underlyingResource = resource.addPath(path);
        if (underlyingResource == null) {
            return null;
        }

        // Cache the resource.
        cached = new CachingResource(underlyingResource, null);
        cached.cache();
        cachedResources.put(fullPath, cached);

        // Return it.
        return cached;
    }
}