View Javadoc

1   package com.atlassian.plugin.servlet.filter;
2   
3   import java.io.IOException;
4   
5   import javax.servlet.Filter;
6   import javax.servlet.FilterChain;
7   import javax.servlet.FilterConfig;
8   import javax.servlet.ServletException;
9   import javax.servlet.ServletRequest;
10  import javax.servlet.ServletResponse;
11  import javax.servlet.http.HttpServletRequest;
12  
13  import com.atlassian.plugin.servlet.PluginHttpRequestWrapper;
14  import com.atlassian.plugin.servlet.descriptors.ServletFilterModuleDescriptor;
15  import com.atlassian.plugin.servlet.util.ClassLoaderStack;
16  
17  /**
18   * We wrap the plugins filter so that we can set some things up before the plugins filter is called. Currently we do 
19   * the following:
20   *      <ul>
21   *        <li>set the Threads classloader to the plugins classloader)</li>
22   *        <li>wrap the request so that path info is right for the filters</li>
23   *      </ul>
24   *      
25   * @since 2.1.0
26   */
27  public class DelegatingPluginFilter implements Filter
28  {
29      private final ServletFilterModuleDescriptor descriptor;
30      private final Filter filter;
31      
32      public DelegatingPluginFilter(ServletFilterModuleDescriptor descriptor)
33      {
34          this.descriptor = descriptor;
35          this.filter = descriptor.getModule();
36      }
37  
38      public void init(FilterConfig filterConfig) throws ServletException
39      {
40          ClassLoaderStack.push(descriptor.getPlugin().getClassLoader());
41          try
42          {
43              filter.init(filterConfig);
44          }
45          finally
46          {
47              ClassLoaderStack.pop();
48          }
49      }
50  
51      public void doFilter(ServletRequest request, ServletResponse response, final FilterChain chain)
52          throws IOException, ServletException
53      {
54          ClassLoaderStack.push(descriptor.getPlugin().getClassLoader());
55          try
56          {
57              // Reset the classloader during chain execution to prevent plugin's classloader being used for the duration
58              // of the request
59              FilterChain resetContextClassLoaderChain = new FilterChain()
60              {
61                  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException, ServletException
62                  {
63                      ClassLoaderStack.pop();
64                      try
65                      {
66                          chain.doFilter(servletRequest, servletResponse);
67                      }
68                      finally
69                      {
70                          ClassLoaderStack.push(descriptor.getPlugin().getClassLoader());
71                      }
72                  }
73              };
74              filter.doFilter(new PluginHttpRequestWrapper((HttpServletRequest) request, descriptor), response, resetContextClassLoaderChain);
75          }
76          finally
77          {
78              ClassLoaderStack.pop();
79          }
80      }
81      
82      public void destroy()
83      {
84          ClassLoaderStack.push(descriptor.getPlugin().getClassLoader());
85          try
86          {
87              filter.destroy();
88          }
89          finally
90          {
91              ClassLoaderStack.pop();
92          }
93      }
94  
95      public Filter getDelegatingFilter()
96      {
97          return filter;
98      }
99  }