1 package com.atlassian.plugins.rest.module;
2
3 import com.atlassian.plugin.AutowireCapablePlugin;
4 import com.atlassian.plugin.osgi.factory.OsgiPlugin;
5 import com.atlassian.plugins.rest.common.filter.ExtensionJerseyFilter;
6 import com.google.common.base.Preconditions;
7 import com.sun.jersey.api.core.ResourceConfig;
8 import com.sun.jersey.spi.container.WebApplication;
9 import com.sun.jersey.spi.container.servlet.ServletContainer;
10 import com.sun.jersey.spi.container.servlet.WebConfig;
11 import org.apache.commons.lang.StringUtils;
12
13 import javax.servlet.Filter;
14 import javax.servlet.FilterChain;
15 import javax.servlet.FilterConfig;
16 import javax.servlet.ServletException;
17 import javax.servlet.ServletRequest;
18 import javax.servlet.ServletResponse;
19 import javax.servlet.http.HttpServletRequest;
20 import javax.servlet.http.HttpServletResponse;
21 import javax.ws.rs.core.UriBuilder;
22 import java.io.IOException;
23 import java.net.URI;
24 import java.util.Map;
25
26
27
28
29
30 class RestDelegatingServletFilter implements Filter
31 {
32
33
34
35 private final ServletContainer servletContainer;
36 private final ResourceConfigManager resourceConfigManager;
37
38 RestDelegatingServletFilter(OsgiPlugin plugin, RestApiContext restContextPath)
39 {
40 resourceConfigManager = new ResourceConfigManager(plugin, plugin.getBundle());
41 this.servletContainer = new JerseyOsgiServletContainer(plugin, restContextPath, resourceConfigManager);
42 }
43
44 public void init(FilterConfig config) throws ServletException
45 {
46 final ClassLoader currentThreadClassLoader = Thread.currentThread().getContextClassLoader();
47 try
48 {
49 Thread.currentThread().setContextClassLoader(new ChainingClassLoader(RestModuleDescriptor.class.getClassLoader(), currentThreadClassLoader));
50 servletContainer.init(config);
51 }
52 finally
53 {
54 Thread.currentThread().setContextClassLoader(currentThreadClassLoader);
55 }
56 }
57
58 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
59 {
60 final ClassLoader currentThreadClassLoader = Thread.currentThread().getContextClassLoader();
61 try
62 {
63 Thread.currentThread().setContextClassLoader(new ChainingClassLoader(RestModuleDescriptor.class.getClassLoader(), currentThreadClassLoader));
64 servletContainer.doFilter(request, response, chain);
65 }
66 finally
67 {
68 Thread.currentThread().setContextClassLoader(currentThreadClassLoader);
69 }
70 }
71
72 public void destroy()
73 {
74 servletContainer.destroy();
75 resourceConfigManager.destroy();
76 }
77
78
79
80
81 private static class JerseyOsgiServletContainer extends ServletContainer
82 {
83 private final AutowireCapablePlugin plugin;
84 private final RestApiContext restApiContext;
85 private final ResourceConfigManager resourceConfigManager;
86
87 private static final String PARAM_EXTENSION_FILTER_EXCLUDES = "extension.filter.excludes";
88
89 public JerseyOsgiServletContainer(AutowireCapablePlugin plugin, RestApiContext restApiContext, final ResourceConfigManager resourceConfigManager)
90 {
91 this.resourceConfigManager = Preconditions.checkNotNull(resourceConfigManager);
92 this.plugin = Preconditions.checkNotNull(plugin);
93 this.restApiContext = Preconditions.checkNotNull(restApiContext);
94 }
95
96 @Override
97 protected ResourceConfig getDefaultResourceConfig(Map<String, Object> props, WebConfig webConfig) throws ServletException
98 {
99
100 final String deprecatedName = "com.atlassian.plugins.rest.module.filter.ExtensionJerseyFilter" + "#excludes";
101 final String excludeParam = webConfig.getInitParameter(deprecatedName) != null ?
102 webConfig.getInitParameter(deprecatedName) : webConfig.getInitParameter(PARAM_EXTENSION_FILTER_EXCLUDES);
103
104 final String[] excludes = StringUtils.split(excludeParam, " ,;");
105
106 return resourceConfigManager.createResourceConfig(props, excludes, restApiContext.getPackages());
107 }
108
109 @Override
110 public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
111 throws IOException, ServletException
112 {
113
114 String baseUriPath;
115 if (request.getRequestURI().contains(restApiContext.getPathToLatest()))
116 {
117 baseUriPath = request.getContextPath() + restApiContext.getPathToLatest();
118 }
119 else
120 {
121 baseUriPath = request.getContextPath() + restApiContext.getPathToVersion();
122 }
123 final UriBuilder absoluteUriBuilder = UriBuilder.fromUri(request.getRequestURL().toString());
124
125 final URI baseUri = absoluteUriBuilder.replacePath(baseUriPath).path("/").build();
126
127 final URI requestUri = absoluteUriBuilder.replacePath(request.getRequestURI()).replaceQuery(
128 request.getQueryString()).build();
129
130 service(baseUri, requestUri, request, response);
131 }
132
133 @Override
134 protected void initiate(ResourceConfig resourceConfig, WebApplication webApplication)
135 {
136 webApplication.initiate(resourceConfig, new OsgiComponentProviderFactory(resourceConfig, plugin));
137 }
138 }
139 }