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

net.contextfw.web.commons.minifier.ContentServlet Maven / Gradle / Ivy

The newest version!
package net.contextfw.web.commons.minifier;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.contextfw.web.application.ResourceCleaner;
import net.contextfw.web.application.WebApplicationException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.Inject;

abstract class ContentServlet extends HttpServlet {

    private static final int SECOND = 1000;

    private static final long serialVersionUID = 1L;
    
    Logger logger = LoggerFactory.getLogger(ContentServlet.class);
    
    private ThreadLocal format = new ThreadLocal() {
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH);
        }
    };

    private volatile String content;
    
    private final String host;
    
    private final String minifiedPath;
    
    private final String version;
    
    private final long started;
    
    private static final long EXPIRATION = 60 * 60 * 1000 * 8;
    
    private ResourceCleaner cleaner;
    
    protected ContentServlet(String host,
                             String minifiedPath,
                             long started,
                             String version) {
        this.host = host;
        this.started = started;
        this.version = version;
        this.minifiedPath = minifiedPath;
        this.modifiedSince = new Date(started);
    }
    
    protected URL getUrl(String src) {
        try {
            return new URL(host + src);
        } catch (MalformedURLException e) {
            throw new WebApplicationException(e);
        }
    }
    
    String getMinifiedPath() {
        return minifiedPath.replaceFirst("", version);
    }
    
    private final Date modifiedSince;
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
            IOException {
        
        if (content == null) {
            synchronized (this) {
                if (content == null) {
                    cleaner.clean();        
                }
            }
        }
        
        resp.setContentType(getContentType());
        String modifiedHeader = req.getHeader("If-Modified-Since");
        Date mod = null;
        
        if (modifiedHeader != null) {
            try {
                mod = format.get().parse(modifiedHeader);
            } catch (ParseException e) {
                logger.error("Error while parsing", e);
            }
        }

        HttpServletResponse httpResponse = (HttpServletResponse) resp;
        httpResponse.setDateHeader("Expires", started + EXPIRATION);
        httpResponse.setDateHeader("Date", started);
        httpResponse.setDateHeader("Last-Modified", started+SECOND);
        httpResponse.setHeader("Cache-Control", "max-age=2246400, must-revalidate");
        httpResponse.setHeader("Pragma", "cache");
        
        if (content != null && mod != null && modifiedSince.before(mod)) {
            resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        } else {
            resp.getWriter().print(content);
        }
    }
    
    protected abstract String getContentType();

    public void setContent(String content) {
        this.content = content;
    }

    @Inject
    public void setCleaner(ResourceCleaner cleaner) {
        this.cleaner = cleaner;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy