Package com.scooterframework.web.controller

Source Code of com.scooterframework.web.controller.ScooterRequestFilter

/*
*   This software is distributed under the terms of the FSF
*   Gnu Lesser General Public License (see lgpl.txt).
*
*   This program is distributed WITHOUT ANY WARRANTY. See the
*   GNU General Public License for more details.
*/
package com.scooterframework.web.controller;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.scooterframework.admin.Constants;
import com.scooterframework.admin.EnvConfig;
import com.scooterframework.common.exception.FileUploadException;
import com.scooterframework.common.logging.LogUtil;
import com.scooterframework.common.util.CurrentThreadCache;
import com.scooterframework.common.util.CurrentThreadCacheClient;
import com.scooterframework.web.route.RequestInfo;

/**
* ScooterRequestFilter can be attached to either an individual servlet
* or to a URL pattern.  This filter performs the following functions:
* <ul>
* <li>Loads property value under the attribute name
*     defined by the value of the <tt>attribute</tt> initialization
*     parameter.</li>
* <li>Initializes WebActionContext.</li>
* <li>Records a bench mark in the response header if specified in environment.properties file.</li>
* <li>Cleans up content cached in the request thread.</li>
* </ul>
*
* <p>The following parameters are allowed to configure this filter in web.xml:</p>
* <pre>
*   Examples:
*     excluded_paths: /images, /javascripts, /layouts, /stylesheets, /css
*           encoding: UTF-8
* </pre>
*
* @author (Fei) John Chen
*/
public class ScooterRequestFilter implements Filter {
    /**
     * Directory paths that we want this filter to skip.
     */
    protected String excludedPaths = null;
   
    /**
     * Character encoding to be used.
     */
    protected String encoding = null;


    /**
     * Place this filter into service.
     *
     * @param filterConfig The filter configuration object
     */
    public void init(FilterConfig filterConfig) throws ServletException {
        this.excludedPaths = filterConfig.getInitParameter("excluded_paths");
        this.encoding = filterConfig.getInitParameter("encoding");
       
        otherInit();
    }
   
    protected void otherInit() {
        //Do something more
    }
   
    /**
     * Take this filter out of service.
     */
    public void destroy() {
        this.excludedPaths = null;
    }

    /**
     * Time the processing that is performed by all subsequent filters in the
     * current filter stack, including the ultimately invoked servlet.
     *
     * @param request The servlet request we are processing
     * @param chain The filter chain we are processing
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet error occurs
     */
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain)
  throws IOException, ServletException
    {
        boolean staticContent = isStaticContentRequest((HttpServletRequest)request);
     
        if (encoding != null) {
            request.setCharacterEncoding(encoding);
            if (!staticContent) {
              response.setCharacterEncoding(encoding);
            }
        }
       
       // boolean skip = skippedRequestPath((HttpServletRequest)request);
        boolean skip = staticContent;
       
        long before = System.currentTimeMillis();
       
        if (!skip) {
            initializeActionContext((HttpServletRequest)request, (HttpServletResponse)response);
        }
        else {
            request.setAttribute(Constants.SKIP_PATH, "Y");
        }
       
        if (isAjaxRequest((HttpServletRequest)request)) {
          request.setAttribute(Constants.SITEMESH_FILTERAPPLIED, Boolean.TRUE);
        }

        String requestPathKeyWithQueryString = requestInfo(skip, (HttpServletRequest)request);
        log.debug("============>>\"" + requestPathKeyWithQueryString + "\"");
       
        try {
          chain.doFilter(request, response);
        } catch (Throwable ex) {
          log.error("Error from chain.doFilter: " + ex.getMessage(), ex);
        }
       
        long after = System.currentTimeMillis();
       
        if (EnvConfig.getInstance().allowRecordBenchmark()) {
            log.info("\"" + requestPathKeyWithQueryString + "\" takes: " + (after - before) + " ms");
            if (EnvConfig.getInstance().allowRecordBenchmarkInHeader()) {
                HttpServletResponseWrapper resw = new HttpServletResponseWrapper((HttpServletResponse)response);
                resw.addHeader("Exec-Time", (after - before) + " ms");
            }
        }
       
        clearCachedRequestData();
    }
   
    protected boolean isStaticContentRequest(HttpServletRequest request) {
        String contextPath = request.getContextPath();
        String requestURI = request.getRequestURI();
        String staticPath = contextPath + "/" + "static";
        return (requestURI.startsWith(staticPath))?true:false;
    }
   
    protected String requestInfo(boolean skipStatic, HttpServletRequest request) {
        String method = getRequestMethod(request);
        String requestPath = getRequestPath(request);
        String requestPathKey = RequestInfo.generateRequestKey(requestPath, method);
        String s = requestPathKey;
        String queryString = request.getQueryString();
        if (queryString != null) s += "?" + queryString;
       
        CurrentThreadCacheClient.cacheHttpMethod(method);
        CurrentThreadCacheClient.cacheRequestPath(requestPath);
        CurrentThreadCacheClient.cacheRequestPathKey(requestPathKey);
       
        if (skipStatic) return s;
       
        //request header
        Properties headers = new Properties();
        Enumeration<?> headerNames = request.getHeaderNames();
        while(headerNames.hasMoreElements()) {
            String name = (String)headerNames.nextElement();
            String value = request.getHeader(name);
            if (value != null) headers.setProperty(name, value);
        }
        CurrentThreadCache.set(Constants.REQUEST_HEADER, headers);
       
        if (isLocalRequest(request)) {
            CurrentThreadCache.set(Constants.LOCAL_REQUEST, Constants.VALUE_FOR_LOCAL_REQUEST);
        }
       
        if (isFileUploadRequest(request)) {
            CurrentThreadCache.set(Constants.FILE_UPLOAD_REQUEST, Constants.VALUE_FOR_FILE_UPLOAD_REQUEST);
           
            try {
              List<FileItem> files = new ArrayList<FileItem>();
                ServletFileUpload fileUpload = EnvConfig.getInstance().getServletFileUpload();
                List<?> items = fileUpload.parseRequest(request);
                for (Object fi : items) {
                  FileItem item = (FileItem)fi;
                  if (item.isFormField()) {
                    ActionControl.storeToRequest(item.getFieldName(), item.getString());
                  }
                  else if (!item.isFormField() && !"".equals(item.getName())) {
                    files.add(item);
                  }
                }
                CurrentThreadCache.set(Constants.FILE_UPLOAD_REQUEST_FILES, files);
            } catch (Exception ex) {
              CurrentThreadCacheClient.storeError(new FileUploadException(ex));
            }
        }
       
        return s;
    }
   
    /**
     * Returns request path of the HttpServletRequest <tt>request</tt>. A
     * request path is a combination of the <tt>request</tt>'s servletPath and pathInfo.
     *
     * @param request HttpServletRequest
     * @return request path
     */
    protected String getRequestPath(HttpServletRequest request) {
        String contextPath = request.getContextPath();
        String requestURI = decode(cleanJsessionid(request.getRequestURI()));
        CurrentThreadCache.set(Constants.REQUEST_URI, requestURI);
       
        String requestPath = requestURI.substring(contextPath.length());
        if (requestPath.length() > 1 &&
            (requestURI.endsWith("/") || requestURI.endsWith("\\"))) {
          requestPath = requestPath.substring(0, requestPath.length()-1);
        }
        return requestPath;
    }
 
  private String decode(String s) {
    String ss = s;
    try {
      ss = URLDecoder.decode(s, "UTF-8");
    } catch (UnsupportedEncodingException e) {
      log.warn("Failed to decode \"" + s + "\" because " + e.getMessage());
    }
    return ss;
  }
 
  private static String cleanJsessionid(String requestPath) {
    String s = requestPath;
    if (s.indexOf(";jsessionid") != -1) {
      s = s.substring(0, s.indexOf(";jsessionid"));
    }
    return s;
  }
   
    /**
     * Returns the method of the <tt>request</tt>.
     */
    protected String getRequestMethod(HttpServletRequest request) {
        String m = request.getParameter(Constants.HTTP_METHOD);
        if (m == null) {
          m = request.getMethod();
        }
        return m.toUpperCase();
    }
   
    protected boolean isAjaxRequest(HttpServletRequest request) {
        return (request.getParameter(Constants.AJAX_REQUEST) != null)?true:false;
    }
   
    /**
     * Cleans up all local cached data to prepare for the next request.
     */
    protected void clearCachedRequestData() {
        CurrentThreadCache.clear();
    }
   
    protected void initializeActionContext(HttpServletRequest request, HttpServletResponse response) {
        WebActionContext wac = new WebActionContext(request, response);
        ACH.setActionContext(wac);
    }
   
    /**
     * Checks if a request path must be skipped.
     *
     * @param request
     * @return true if the request path should be skipped.
     */
    protected boolean skippedRequestPath(HttpServletRequest request) {
        if (excludedPaths == null || "Y".equals(request.getAttribute(Constants.SKIP_PATH))) return true;
       
        String contextPath = request.getContextPath();
        String uriPath = request.getRequestURI();
        String servletPathInfo = "";
        String requestPathDir = uriPath;
        if (uriPath.length() > contextPath.length()) {
            servletPathInfo = uriPath.substring(contextPath.length());
            requestPathDir = servletPathInfo;
            int secondSlashIndex = servletPathInfo.indexOf("/", 1);
            if (secondSlashIndex != -1) requestPathDir = servletPathInfo.substring(0, secondSlashIndex);
        }
       
        boolean status = false;
        if (!"/".equals(requestPathDir) && excludedPaths.indexOf(requestPathDir) != -1) {
            status = true;
        }
       
        log.debug("skip = " + status + " for " + servletPathInfo);
        return status;
    }
   
    protected boolean isLocalRequest(HttpServletRequest request) {
        String requestURL = request.getRequestURL().toString();
        String remoteAddr = request.getRemoteAddr();
        String remoteHost = request.getRemoteHost();
        if (requestURL.startsWith(Constants.LOCAL_HOST_URL_PREFIX_1) ||
            requestURL.startsWith(Constants.LOCAL_HOST_URL_PREFIX_2) ||
            requestURL.startsWith(Constants.LOCAL_HOST_URL_PREFIX_3) ||
            requestURL.startsWith(Constants.LOCAL_HOST_URL_PREFIX_4) ||
            remoteAddr.equals(Constants.LOCAL_HOST_REMOTE_ADDRESS) ||
            remoteHost.equals(Constants.LOCAL_HOST_REMOTE_HOST_1) ||
            remoteHost.equals(Constants.LOCAL_HOST_REMOTE_HOST_2)) {
            return true;
        }
        return false;
    }
   
    protected boolean isFileUploadRequest(HttpServletRequest request) {
      return ServletFileUpload.isMultipartContent(request);
    }

    protected LogUtil log = LogUtil.getLogger(this.getClass().getName());
}
TOP

Related Classes of com.scooterframework.web.controller.ScooterRequestFilter

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.