Package cssvar.servlet

Source Code of cssvar.servlet.CSSVarServlet

package cssvar.servlet;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.Scanner;

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

import org.apache.log4j.Logger;

import cssvar.CSSVarContext;
import cssvar.filter.CSSVarFilter;

/**
*
* A stand-alone Servlet for handling requests for .css files containing CSSVar
* syntax
*
* Upon initialization, a context-wide CSS variable context is loaded from a
* default properties file.
*
* On a request, the target css file is found and run through a CSSVarFilter,
* resolving all variable references and outputting valid CSS which can be
* streamed back to the client.
*
* @author Alex Wyler
*
*/
public class CSSVarServlet extends HttpServlet {

  private static final long serialVersionUID = 1L;

  public static final String GLOBAL_CONTEXT_KEY = "cssvar.global.context";
  private static final String DEFAULT_CONFIG_PATH = "/WEB-INF/classes/cssvar.properties";
  private static final String EXT_CACHED = ".filtered";

  private static final Logger LOG = Logger.getLogger(CSSVarServlet.class);

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    ServletContext ctx = req.getSession().getServletContext();

    CSSVarContext globalCSSContext = (CSSVarContext) ctx
        .getAttribute(GLOBAL_CONTEXT_KEY);

    resp.setContentType("text/css");

    String targetFilepath = getTargetFilePath(req);
    File filteredFile = new File(targetFilepath + EXT_CACHED);
    long lastFilterTime = (filteredFile.exists()) ? filteredFile
        .lastModified() : 0;

    if (lastFilterTime < getLastModified(req)) {
      LOG.debug("No up-to-date, cached version of "
          + filteredFile.getName()
          + " can be found.  The input will be parsed and cached.");
      CSSVarFilter filter = new CSSVarFilter();
      filter.filterCSS(new File(targetFilepath), filteredFile,
          globalCSSContext);
      for (String error : filter.getErrors()) {
        LOG.error(error);
      }
    } else {
      LOG.debug("Return cached, up-to-date version of "
          + filteredFile.getName() + ".");
    }

    if (filteredFile.exists()) {
      Scanner parsedOutputScanner = new Scanner(filteredFile);
      while (parsedOutputScanner.hasNextLine()) {
        String line = parsedOutputScanner.nextLine();

        resp.getWriter().write(line + "\r\n");
      }
    }
  }

  /**
   * Initializes the global CSSVar context from a default configuration file.
   *
   * TODO: allow other configuration options
   */
  @Override
  public void init(ServletConfig config) throws ServletException {
    super.init(config);

    ServletContext ctx = config.getServletContext();
    File defaultConfig = new File(ctx.getRealPath(DEFAULT_CONFIG_PATH));

    LOG.info("Loading global CSSVar context");
    try {
      ctx.setAttribute(CSSVarServlet.GLOBAL_CONTEXT_KEY,
          new CSSVarContext(defaultConfig));
    } catch (Exception e) {
      LOG.warn("Unable to load default config file \""
          + DEFAULT_CONFIG_PATH
          + "\". CSS files will start with an empty global var context.");
    }
  }

  /**
   * Returns the time of the most recent modification to either the
   * servlet-wide CSSVar Context or the requested CSS file.
   *
   * This is used to properly return status '304' on conditional-get requests.
   */
  @Override
  protected long getLastModified(HttpServletRequest req) {

    long currTime = new Date().getTime();

    File targetFile = new File(getTargetFilePath(req));
    long cssModified = targetFile.exists() ? targetFile.lastModified()
        : currTime;

    ServletContext ctx = req.getSession().getServletContext();
    CSSVarContext globalCSSContext = (CSSVarContext) ctx
        .getAttribute(GLOBAL_CONTEXT_KEY);
    long cssvarContextModified = globalCSSContext != null ? globalCSSContext
        .getLastInit() : currTime;

    return Math.max(cssModified, cssvarContextModified);
  }

  /**
   * Parses the target css filepath from the requst.
   */
  private String getTargetFilePath(HttpServletRequest req) {
    ServletContext ctx = req.getSession().getServletContext();
    String relativePath = req.getRequestURL().toString()
        .split(ctx.getContextPath())[1];
    return ctx.getRealPath(relativePath);
  }

  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    doGet(req, resp);
  }

}
TOP

Related Classes of cssvar.servlet.CSSVarServlet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.