FileCacheStore.java 6.48 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  javax.servlet.http.HttpServletRequest
 *  org.apache.commons.lang.StringUtils
 *  org.apache.felix.scr.annotations.Activate
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.ConfigurationPolicy
 *  org.apache.felix.scr.annotations.Modified
 *  org.apache.felix.scr.annotations.Property
 *  org.apache.felix.scr.annotations.Service
 *  org.apache.sling.commons.osgi.OsgiUtil
 *  org.osgi.service.component.ComponentContext
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.granite.httpcache.file;

import com.adobe.granite.httpcache.api.CacheFile;
import com.adobe.granite.httpcache.api.CacheKeyGenerator;
import com.adobe.granite.httpcache.api.CacheStore;
import com.adobe.granite.httpcache.api.Headers;
import com.adobe.granite.httpcache.file.StoredCacheFile;
import com.adobe.granite.httpcache.file.TemporaryCacheFile;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.ConfigurationPolicy;
import org.apache.felix.scr.annotations.Modified;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.commons.osgi.OsgiUtil;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/*
 * This class specifies class file version 49.0 but uses Java 6 signatures.  Assumed Java 6.
 */
@Component(label="Adobe Granite HTTP File Cache Store", description="File Cache Store", metatype=1, immediate=1, policy=ConfigurationPolicy.REQUIRE)
@Service(value={CacheStore.class, CacheKeyGenerator.class})
public class FileCacheStore
implements CacheStore,
CacheKeyGenerator {
    private static Logger logger = LoggerFactory.getLogger(FileCacheStore.class);
    @Property(label="Directory", description="Cache document root")
    private static final String PROPERTY_DIRECTORY = "com.adobe.granite.httpcache.file.documentRoot";
    @Property(label="IncludeHost", description="Whether to include host name in document root")
    private static final String PROPERTY_INCLUDE_HOST = "com.adobe.granite.httpcache.file.includeHost";
    private File documentRoot;
    private boolean includeHost;
    private static final byte[] RESERVED_FS_CHARACTERS = new byte[]{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0};

    @Activate
    @Modified
    private void activate(ComponentContext context, Map<String, Object> configuration) {
        String pid = (String)configuration.get("service.pid");
        this.includeHost = OsgiUtil.toBoolean((Object)configuration.get("com.adobe.granite.httpcache.file.includeHost"), (boolean)false);
        String value = OsgiUtil.toString((Object)configuration.get("com.adobe.granite.httpcache.file.documentRoot"), (String)null);
        if (StringUtils.isBlank((String)value)) {
            logger.error("Mandatory property not configured: {}.", (Object)"com.adobe.granite.httpcache.file.documentRoot");
        } else if (this.setDirectory(value)) {
            return;
        }
        context.disableComponent(pid);
    }

    boolean setDirectory(String value) {
        File directory = new File(value);
        if (!(directory.exists() || directory.mkdirs() || directory.exists())) {
            logger.error("Unable to create document root: {}.", (Object)directory);
            return false;
        }
        if (!directory.isDirectory()) {
            logger.error("Path does not denote a directory: {}.", (Object)directory);
            return false;
        }
        this.documentRoot = directory;
        return true;
    }

    @Override
    public CacheFile create(String key, Headers headers) throws IOException {
        String relativePath = FileCacheStore.mapToFSPath(key);
        File file = new File(this.documentRoot, relativePath);
        return new TemporaryCacheFile(key, headers, file);
    }

    @Override
    public CacheFile lookup(String key) {
        String relativePath = FileCacheStore.mapToFSPath(key);
        File file = new File(this.documentRoot, relativePath);
        if (file.isFile()) {
            return new StoredCacheFile(key, file);
        }
        return null;
    }

    @Override
    public boolean evict(String key) {
        String relativePath = FileCacheStore.mapToFSPath(key);
        File file = new File(this.documentRoot, relativePath);
        if (file.isFile()) {
            return file.delete();
        }
        return false;
    }

    private File getDocumentRoot(String host) {
        if (this.includeHost) {
            return new File(this.documentRoot, host);
        }
        return this.documentRoot;
    }

    @Override
    public void evictAll(String host, String path) {
        final File file = new File(this.getDocumentRoot(host), FileCacheStore.mapToFSPath(path));
        File[] list = file.getParentFile().listFiles(new FileFilter(){

            public boolean accept(File pathname) {
                return pathname.isFile() && pathname.getName().startsWith(file.getName());
            }
        });
        if (list != null) {
            for (File f : list) {
                logger.trace("Deleting {}", (Object)f);
                f.delete();
            }
        }
    }

    @Override
    public String generate(HttpServletRequest request) {
        if (this.includeHost) {
            return request.getServerName() + '/' + request.getRequestURI();
        }
        return request.getRequestURI();
    }

    static String mapToFSPath(String key) {
        if (key.charAt(0) == '/') {
            key = key.substring(1);
        }
        if (File.separatorChar != '/') {
            key = key.replace('/', File.separatorChar);
        }
        char[] ch = key.toCharArray();
        for (int i = 0; i < ch.length; ++i) {
            char c = ch[i];
            if (c >= RESERVED_FS_CHARACTERS.length || RESERVED_FS_CHARACTERS[c] != 1 || c == File.separatorChar) continue;
            ch[i] = 95;
        }
        return new String(ch);
    }

}