View Javadoc

1   package com.atlassian.plugin.servlet.filter;
2   
3   import com.atlassian.plugin.servlet.ServletModuleManager;
4   import com.atlassian.plugin.servlet.util.ServletContextHostContainerAccessor;
5   import org.apache.commons.logging.Log;
6   import org.apache.commons.logging.LogFactory;
7   
8   import javax.servlet.*;
9   import javax.servlet.http.HttpServletRequest;
10  import javax.servlet.http.HttpServletResponse;
11  import java.io.IOException;
12  
13  /**
14   * Applications need to create a concrete subclass of this for use in their filter stack.  This filters responsiblity
15   * is to retrieve the filters to be applied to the request from the {@link ServletModuleManager} and build a
16   * {@link FilterChain} from them.  Once all the filters in the chain have been applied to the request, this filter
17   * returns control to the main chain.
18   * <p/>
19   * There is one init parameters that must be configured for this filter, the "location" parameter.  It can be one of
20   * "top", "middle" or "bottom".  A filter with a "top" location must appear before the filter with a "middle" location
21   * which must appear before a filter with a "bottom" location.  Where any other application filters lie in the filter
22   * stack is completely up to the application.
23   *
24   * @since 2.1.0
25   */
26  public class ServletFilterModuleContainerFilter implements Filter
27  {
28      private static final Log log = LogFactory.getLog(ServletFilterModuleContainerFilter.class);
29  
30      private FilterConfig filterConfig;
31      private FilterLocation location;
32  
33      public void init(FilterConfig filterConfig) throws ServletException
34      {
35          this.filterConfig = filterConfig;
36          location = FilterLocation.parse(filterConfig.getInitParameter("location"));
37      }
38  
39      public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
40      {
41          doFilter((HttpServletRequest) request, (HttpServletResponse) response, chain);
42      }
43  
44      void doFilter(HttpServletRequest request, HttpServletResponse response, final FilterChain chain) throws IOException, ServletException
45      {
46          if (getServletModuleManager() == null)
47          {
48              log.info("Could not get ServletModuleManager. Skipping filter plugins.");
49              chain.doFilter(request, response);
50              return;
51          }
52  
53          final Iterable<Filter> filters = getServletModuleManager().getFilters(location, getUri(request), filterConfig);
54          FilterChain pluginFilterChain = new IteratingFilterChain(filters.iterator(), chain);
55          pluginFilterChain.doFilter(request, response);
56      }
57  
58      public void destroy()
59      {
60      }
61  
62      /**
63       * Retrieve the DefaultServletModuleManager from your container framework.  Uses the {@link com.atlassian.plugin.servlet.util.ServletContextHostContainerAccessor}
64       * by default.
65       */
66      protected ServletModuleManager getServletModuleManager()
67      {
68          return ServletContextHostContainerAccessor.getHostContainer(filterConfig.getServletContext()).getInstance(ServletModuleManager.class);
69      }
70  
71      protected final FilterConfig getFilterConfig()
72      {
73          return filterConfig;
74      }
75  
76      protected final FilterLocation getFilterLocation()
77      {
78          return location;
79      }
80  
81      /**
82       * Gets the uri from the request.  Copied from Struts 2.1.0.
83       *
84       * @param request The request
85       * @return The uri
86       */
87      private static String getUri(HttpServletRequest request)
88      {
89          // handle http dispatcher includes.
90          String uri = (String) request
91                  .getAttribute("javax.servlet.include.servlet_path");
92          if (uri != null)
93          {
94              return uri;
95          }
96  
97          uri = getServletPath(request);
98          if (uri != null && !"".equals(uri))
99          {
100             return uri;
101         }
102 
103         uri = request.getRequestURI();
104         return uri.substring(request.getContextPath().length());
105     }
106 
107     /**
108      * Retrieves the current request servlet path.
109      * Deals with differences between servlet specs (2.2 vs 2.3+).
110      * Copied from Struts 2.1.0.
111      *
112      * @param request the request
113      * @return the servlet path
114      */
115     private static String getServletPath(HttpServletRequest request)
116     {
117         String servletPath = request.getServletPath();
118 
119         String requestUri = request.getRequestURI();
120         // Detecting other characters that the servlet container cut off (like anything after ';')
121         if (requestUri != null && servletPath != null && !requestUri.endsWith(servletPath))
122         {
123             int pos = requestUri.indexOf(servletPath);
124             if (pos > -1)
125             {
126                 servletPath = requestUri.substring(requestUri.indexOf(servletPath));
127             }
128         }
129 
130         if (null != servletPath && !"".equals(servletPath))
131         {
132             return servletPath;
133         }
134 
135         int startIndex = request.getContextPath().equals("") ? 0 : request.getContextPath().length();
136         int endIndex = request.getPathInfo() == null ? requestUri.length() : requestUri.lastIndexOf(request.getPathInfo());
137 
138         if (startIndex > endIndex)
139         { // this should not happen
140             endIndex = startIndex;
141         }
142 
143         return requestUri.substring(startIndex, endIndex);
144     }
145 }