1 package com.atlassian.plugin.servlet.filter;
2
3 import com.atlassian.plugin.servlet.PluginHttpRequestWrapper;
4 import com.atlassian.plugin.servlet.descriptors.ServletFilterModuleDescriptor;
5 import com.atlassian.plugin.util.ClassLoaderStack;
6
7 import javax.servlet.Filter;
8 import javax.servlet.FilterChain;
9 import javax.servlet.FilterConfig;
10 import javax.servlet.ServletException;
11 import javax.servlet.ServletRequest;
12 import javax.servlet.ServletResponse;
13 import javax.servlet.http.HttpServletRequest;
14 import java.io.IOException;
15
16
17
18
19
20
21
22
23
24
25
26 public class DelegatingPluginFilter implements Filter {
27 private final ServletFilterModuleDescriptor descriptor;
28 private final Filter filter;
29
30 public DelegatingPluginFilter(ServletFilterModuleDescriptor descriptor) {
31 this.descriptor = descriptor;
32 this.filter = descriptor.getModule();
33 }
34
35 public void init(FilterConfig filterConfig) throws ServletException {
36 ClassLoaderStack.push(descriptor.getPlugin().getClassLoader());
37 try {
38 filter.init(filterConfig);
39 } finally {
40 ClassLoaderStack.pop();
41 }
42 }
43
44 public void doFilter(ServletRequest request, ServletResponse response, final FilterChain chain)
45 throws IOException, ServletException {
46
47
48
49 final ClassLoader pluginClassLoader = descriptor.getPlugin().getClassLoader();
50 ClassLoaderStack.push(pluginClassLoader);
51 try {
52
53
54 FilterChain resetContextClassLoaderChain = (servletRequest, servletResponse) -> {
55 ClassLoaderStack.pop();
56 try {
57 chain.doFilter(servletRequest, servletResponse);
58 } finally {
59 ClassLoaderStack.push(pluginClassLoader);
60 }
61 };
62 filter.doFilter(createPluginHttpRequestWrapper((HttpServletRequest) request, descriptor), response, resetContextClassLoaderChain);
63 } finally {
64 ClassLoaderStack.pop();
65 }
66 }
67
68 private PluginHttpRequestWrapper createPluginHttpRequestWrapper(HttpServletRequest request, ServletFilterModuleDescriptor descriptor) {
69 return request instanceof PluginHttpRequestWrapper ? (PluginHttpRequestWrapper) request
70 : new PluginHttpRequestWrapper(request, descriptor);
71 }
72
73 public void destroy() {
74 ClassLoaderStack.push(descriptor.getPlugin().getClassLoader());
75 try {
76 filter.destroy();
77 } finally {
78 ClassLoaderStack.pop();
79 }
80 }
81
82 public Filter getDelegatingFilter() {
83 return filter;
84 }
85 }