View Javadoc
1   /*******************************************************************************
2    *   Gisgraphy Project 
3    * 
4    *   This library is free software; you can redistribute it and/or
5    *   modify it under the terms of the GNU Lesser General Public
6    *   License as published by the Free Software Foundation; either
7    *   version 2.1 of the License, or (at your option) any later version.
8    * 
9    *   This library is distributed in the hope that it will be useful,
10   *   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   *   Lesser General Public License for more details.
13   * 
14   *   You should have received a copy of the GNU Lesser General Public
15   *   License along with this library; if not, write to the Free Software
16   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
17   * 
18   *  Copyright 2008  Gisgraphy project 
19   *  David Masclet <davidmasclet@gisgraphy.com>
20   *  
21   *  
22   *******************************************************************************/
23  package com.gisgraphy.webapp.filter;
24  
25  import java.io.IOException;
26  import java.util.Iterator;
27  import java.util.Set;
28  
29  import javax.servlet.FilterChain;
30  import javax.servlet.RequestDispatcher;
31  import javax.servlet.ServletException;
32  import javax.servlet.http.HttpServletRequest;
33  import javax.servlet.http.HttpServletResponse;
34  
35  import org.apache.commons.lang.StringUtils;
36  import org.springframework.util.PatternMatchUtils;
37  import org.springframework.web.filter.OncePerRequestFilter;
38  import org.springframework.web.util.UrlPathHelper;
39  
40  /**
41   * A simple filter that allows the application to continue using the .html
42   * prefix for actions but also allows static files to be served up with the same
43   * extension. Dojo to serve up its HTML template code. The filter works on an
44   * include/exclude basis where all requests for active pages are redirected by
45   * the filter to thee dispatch servlet. All Dojo related .html requests are
46   * allowed to pass straight through to be processed by the servlet container as
47   * per normal.
48   */
49  public class StaticFilter extends OncePerRequestFilter {
50      private final static String DEFAULT_INCLUDES = "*.html";
51  
52      private final static String DEFAULT_EXCLUDES = "";
53  
54      private static final String INCLUDES_PARAMETER = "includes";
55  
56      private static final String EXCLUDES_PARAMETER = "excludes";
57  
58      private static final String SERVLETNAME_PARAMETER = "servletName";
59  
60      private String[] excludes;
61  
62      private String[] includes;
63  
64      private String servletName = null;
65  
66      /**
67       * Read the includes/excludes paramters and set the filter accordingly.
68       */
69      @Override
70      public void initFilterBean() {
71  	String includesParam = getFilterConfig().getInitParameter(
72  		INCLUDES_PARAMETER);
73  	if (StringUtils.isEmpty(includesParam)) {
74  	    includes = parsePatterns(DEFAULT_INCLUDES);
75  	} else {
76  	    includes = parsePatterns(includesParam);
77  	}
78  
79  	String excludesParam = getFilterConfig().getInitParameter(
80  		EXCLUDES_PARAMETER);
81  	if (StringUtils.isEmpty(excludesParam)) {
82  	    excludes = parsePatterns(DEFAULT_EXCLUDES);
83  	} else {
84  	    excludes = parsePatterns(excludesParam);
85  	}
86  	// if servletName is specified, set it
87  	servletName = getFilterConfig().getInitParameter(SERVLETNAME_PARAMETER);
88      }
89  
90      @SuppressWarnings("unchecked")
91      private String[] parsePatterns(String delimitedPatterns) {
92  	// make sure no patterns are repeated.
93  	Set<String> patternSet = org.springframework.util.StringUtils
94  		.commaDelimitedListToSet(delimitedPatterns);
95  	String[] patterns = new String[patternSet.size()];
96  	int i = 0;
97  	for (Iterator<String> iterator = patternSet.iterator(); iterator
98  		.hasNext(); i++) {
99  	    // no trailing/leading white space.
100 	    String pattern = (String) iterator.next();
101 	    patterns[i] = pattern.trim();
102 	}
103 	return patterns;
104     }
105 
106     /**
107      * This method checks to see if the current path matches includes or
108      * excludes. If it matches includes and not excludes, it forwards to the
109      * static resource and ends the filter chain. Otherwise, it forwards to the
110      * next filter in the chain.
111      * 
112      * @param request
113      *                the current request
114      * @param response
115      *                the current response
116      * @param chain
117      *                the filter chain
118      * @throws ServletException
119      *                 when something goes wrong
120      * @throws IOException
121      *                 when something goes terribly wrong
122      */
123     @Override
124     public void doFilterInternal(HttpServletRequest request,
125 	    HttpServletResponse response, FilterChain chain)
126 	    throws IOException, ServletException {
127 
128 	UrlPathHelper urlPathHelper = new UrlPathHelper();
129 	String path = urlPathHelper.getPathWithinApplication(request);
130 	boolean pathExcluded = PatternMatchUtils.simpleMatch(excludes, path);
131 	boolean pathIncluded = PatternMatchUtils.simpleMatch(includes, path);
132 
133 	if (pathIncluded && !pathExcluded) {
134 	    if (logger.isDebugEnabled()) {
135 		logger.debug("Forwarding to static resource: " + path);
136 	    }
137 
138 	    if (path.contains(".html")) {
139 		response.setContentType("text/html");
140 	    }
141 
142 	    RequestDispatcher rd = getServletContext().getRequestDispatcher(
143 		    path);
144 	    rd.include(request, response);
145 	    return;
146 	}
147 
148 	if (servletName != null) {
149 	    RequestDispatcher rd = getServletContext().getNamedDispatcher(
150 		    servletName);
151 	    rd.forward(request, response);
152 	    return;
153 	}
154 
155 	chain.doFilter(request, response);
156     }
157 }