PageRenderTime 23ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/atlassian-plugins-servlet/src/main/java/com/atlassian/plugin/servlet/PluginServletContextWrapper.java

https://bitbucket.org/purewind/atlassian-plugins
Java | 401 lines | 286 code | 63 blank | 52 comment | 11 complexity | 851c24b3cd82f40a32af6201db48c91d MD5 | raw file
  1. package com.atlassian.plugin.servlet;
  2. import com.atlassian.plugin.Plugin;
  3. import javax.servlet.Filter;
  4. import javax.servlet.FilterRegistration;
  5. import javax.servlet.RequestDispatcher;
  6. import javax.servlet.Servlet;
  7. import javax.servlet.ServletContext;
  8. import javax.servlet.ServletException;
  9. import javax.servlet.ServletRegistration;
  10. import javax.servlet.SessionCookieConfig;
  11. import javax.servlet.SessionTrackingMode;
  12. import javax.servlet.descriptor.JspConfigDescriptor;
  13. import javax.servlet.http.HttpServlet;
  14. import java.io.InputStream;
  15. import java.lang.reflect.InvocationTargetException;
  16. import java.lang.reflect.Method;
  17. import java.net.MalformedURLException;
  18. import java.net.URL;
  19. import java.util.Collection;
  20. import java.util.Collections;
  21. import java.util.Enumeration;
  22. import java.util.EventListener;
  23. import java.util.HashSet;
  24. import java.util.Map;
  25. import java.util.Set;
  26. import java.util.concurrent.ConcurrentMap;
  27. /**
  28. * A wrapper around servlet context that allows plugin servlets to add
  29. * attributes which will not be shared/clobbered by other plugins.
  30. */
  31. public class PluginServletContextWrapper implements ServletContext {
  32. private final ServletModuleManager servletModuleManager;
  33. private final Plugin plugin;
  34. private final ServletContext context;
  35. private final ConcurrentMap<String, Object> attributes;
  36. private final Map<String, String> initParams;
  37. private final Method methodGetContextPath;
  38. public PluginServletContextWrapper(ServletModuleManager servletModuleManager, Plugin plugin, ServletContext context, ConcurrentMap<String, Object> attributes, Map<String, String> initParams) {
  39. Method tmpMethod = null;
  40. this.servletModuleManager = servletModuleManager;
  41. this.plugin = plugin;
  42. this.context = context;
  43. this.attributes = attributes;
  44. this.initParams = initParams;
  45. Class<?> cls = context.getClass();
  46. try {
  47. tmpMethod = cls.getMethod("getContextPath");
  48. } catch (NoSuchMethodException e) {
  49. // no problem, Servlet 2.4 or earlier found
  50. }
  51. methodGetContextPath = tmpMethod;
  52. }
  53. /**
  54. * <p>Gets the named attribute. The attribute is first looked for in the local
  55. * attribute map, if it is not found there it is looked for in the wrapped
  56. * contexts attribute map. If it is not there, null is returned.</p>
  57. *
  58. * <p>A consequence of this ordering is that servlets may, in their own
  59. * context, override but not overwrite attributes from the wrapped context.</p>
  60. */
  61. @Override
  62. public Object getAttribute(String name) {
  63. Object attr = attributes.get(name);
  64. if (attr == null)
  65. attr = context.getAttribute(name);
  66. return attr;
  67. }
  68. /**
  69. * @return an enumeration of all the attributes from the wrapped
  70. * context as well as the local attributes.
  71. */
  72. @Override
  73. public Enumeration<String> getAttributeNames() {
  74. Collection<String> names = new HashSet<String>();
  75. names.addAll(attributes.keySet());
  76. names.addAll(Collections.list(context.getAttributeNames()));
  77. return Collections.enumeration(names);
  78. }
  79. /**
  80. * Removes an attribute from the local context. Leaves the wrapped context
  81. * completely untouched.
  82. */
  83. @Override
  84. public void removeAttribute(String name) {
  85. attributes.remove(name);
  86. }
  87. /**
  88. * <p>Sets an attribute in the local attribute map, leaving the wrapped
  89. * context untouched.</p>
  90. *
  91. * <p>Servlets may use this and the lookup ordering of the
  92. * <code>getAttribute()</code> method to effectively override the value
  93. * of an attribute in the wrapped servlet context with their own value and
  94. * this overridden value will only be seen in the plugins own scope.</p>
  95. */
  96. @Override
  97. public void setAttribute(String name, Object object) {
  98. attributes.put(name, object);
  99. }
  100. /**
  101. * @return the init parameter from the servlet module descriptor.
  102. */
  103. @Override
  104. public String getInitParameter(String name) {
  105. return initParams.get(name);
  106. }
  107. /**
  108. * @return an enumeration of the init parameters from the servlet module
  109. * descriptor.
  110. */
  111. @Override
  112. public Enumeration<String> getInitParameterNames() {
  113. return Collections.enumeration(initParams.keySet());
  114. }
  115. /**
  116. * @return the resource from the plugin classloader if it exists, otherwise the
  117. * resource is looked up from the wrapped context and returned
  118. */
  119. @Override
  120. public URL getResource(String path) throws MalformedURLException {
  121. URL url = plugin.getResource(path);
  122. if (url == null) {
  123. url = context.getResource(path);
  124. }
  125. return url;
  126. }
  127. /**
  128. * @return the resource stream from the plugin classloader if it exists, otherwise
  129. * the resource stream is attempted to be retrieved from the wrapped context
  130. */
  131. @Override
  132. public InputStream getResourceAsStream(String path) {
  133. InputStream in = plugin.getResourceAsStream(path);
  134. if (in == null) {
  135. in = context.getResourceAsStream(path);
  136. }
  137. return in;
  138. }
  139. /**
  140. * @return null so that servlet plugins can't escape their box
  141. */
  142. @Override
  143. public ServletContext getContext(String uripath) {
  144. return null;
  145. }
  146. @Override
  147. public String getContextPath() {
  148. // all this crap to deal with Servlet 2.4 containers better
  149. if (methodGetContextPath != null) {
  150. try {
  151. return (String) methodGetContextPath.invoke(context);
  152. } catch (IllegalAccessException e) {
  153. throw new RuntimeException("Cannot access this method", e);
  154. } catch (InvocationTargetException e) {
  155. throw new RuntimeException("Unable to execute getContextPath()", e.getCause());
  156. }
  157. } else {
  158. throw new UnsupportedOperationException("This servlet context doesn't support 2.5 methods");
  159. }
  160. }
  161. //---- All methods below simply delegate to the wrapped servlet context ----
  162. @Override
  163. public int getMajorVersion() {
  164. return context.getMajorVersion();
  165. }
  166. @Override
  167. public String getMimeType(String file) {
  168. return context.getMimeType(file);
  169. }
  170. @Override
  171. public int getMinorVersion() {
  172. return context.getMinorVersion();
  173. }
  174. @Override
  175. public RequestDispatcher getNamedDispatcher(String name) {
  176. return context.getNamedDispatcher(name);
  177. }
  178. @Override
  179. public String getRealPath(String path) {
  180. return context.getRealPath(path);
  181. }
  182. @Override
  183. public RequestDispatcher getRequestDispatcher(String path) {
  184. return context.getRequestDispatcher(path);
  185. }
  186. @Override
  187. public Set<String> getResourcePaths(String arg0) {
  188. return context.getResourcePaths(arg0);
  189. }
  190. @Override
  191. public String getServerInfo() {
  192. return context.getServerInfo();
  193. }
  194. @Override
  195. public Servlet getServlet(String name) throws ServletException {
  196. return context.getServlet(name);
  197. }
  198. @Override
  199. public String getServletContextName() {
  200. return context.getServletContextName();
  201. }
  202. @Override
  203. public Enumeration<String> getServletNames() {
  204. return context.getServletNames();
  205. }
  206. @Override
  207. public Enumeration<Servlet> getServlets() {
  208. return context.getServlets();
  209. }
  210. @Override
  211. public void log(Exception exception, String msg) {
  212. context.log(exception, msg);
  213. }
  214. @Override
  215. public void log(String message, Throwable throwable) {
  216. context.log(message, throwable);
  217. }
  218. @Override
  219. public void log(String msg) {
  220. context.log(msg);
  221. }
  222. //---- Servlet 3.0 methods ----
  223. @Override
  224. public boolean setInitParameter(String name, String value) {
  225. if (initParams.containsKey(name)) {
  226. return false;
  227. }
  228. initParams.put(name, value);
  229. return true;
  230. }
  231. @Override
  232. public int getEffectiveMajorVersion() {
  233. return context.getEffectiveMajorVersion();
  234. }
  235. @Override
  236. public int getEffectiveMinorVersion() {
  237. return context.getEffectiveMinorVersion();
  238. }
  239. @Override
  240. public SessionCookieConfig getSessionCookieConfig() {
  241. return context.getSessionCookieConfig();
  242. }
  243. @Override
  244. public void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes) {
  245. context.setSessionTrackingModes(sessionTrackingModes);
  246. }
  247. @Override
  248. public Set<SessionTrackingMode> getDefaultSessionTrackingModes() {
  249. return context.getDefaultSessionTrackingModes();
  250. }
  251. @Override
  252. public Set<SessionTrackingMode> getEffectiveSessionTrackingModes() {
  253. return context.getEffectiveSessionTrackingModes();
  254. }
  255. @Override
  256. public JspConfigDescriptor getJspConfigDescriptor() {
  257. return context.getJspConfigDescriptor();
  258. }
  259. @Override
  260. public ClassLoader getClassLoader() {
  261. return context.getClassLoader();
  262. }
  263. @Override
  264. public void declareRoles(String... roleNames) {
  265. context.declareRoles(roleNames);
  266. }
  267. @Override
  268. public ServletRegistration.Dynamic addServlet(String servletName, String className) {
  269. servletModuleManager.addServlet(plugin, servletName, className);
  270. return null;
  271. }
  272. @Override
  273. public ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet) {
  274. // atlassian-plugins limitation - HttpServlet only
  275. if (!(servlet instanceof HttpServlet)) {
  276. throw new IllegalArgumentException("only javax.servlet.http.HttpServlet is supported by atlassian-plugins for javax.servlet.ServletContext#addServlet(String, javax.servlet.Servlet)}");
  277. }
  278. servletModuleManager.addServlet(plugin, servletName, (HttpServlet) servlet, this);
  279. return null;
  280. }
  281. @Override
  282. public ServletRegistration.Dynamic addServlet(String servletName, Class<? extends Servlet> servletClass) {
  283. servletModuleManager.addServlet(plugin, servletName, servletClass.getName());
  284. return null;
  285. }
  286. @Override
  287. public <T extends Servlet> T createServlet(Class<T> clazz) {
  288. throw new UnsupportedOperationException();
  289. }
  290. @Override
  291. public ServletRegistration getServletRegistration(String servletName) {
  292. throw new UnsupportedOperationException();
  293. }
  294. @Override
  295. public Map<String, ? extends ServletRegistration> getServletRegistrations() {
  296. throw new UnsupportedOperationException();
  297. }
  298. @Override
  299. public FilterRegistration.Dynamic addFilter(String filterName, String className) {
  300. throw new UnsupportedOperationException();
  301. }
  302. @Override
  303. public FilterRegistration.Dynamic addFilter(String filterName, Filter filter) {
  304. throw new UnsupportedOperationException();
  305. }
  306. @Override
  307. public FilterRegistration.Dynamic addFilter(String filterName, Class<? extends Filter> filterClass) {
  308. throw new UnsupportedOperationException();
  309. }
  310. @Override
  311. public <T extends Filter> T createFilter(Class<T> clazz) {
  312. throw new UnsupportedOperationException();
  313. }
  314. @Override
  315. public FilterRegistration getFilterRegistration(String filterName) {
  316. throw new UnsupportedOperationException();
  317. }
  318. @Override
  319. public Map<String, ? extends FilterRegistration> getFilterRegistrations() {
  320. throw new UnsupportedOperationException();
  321. }
  322. @Override
  323. public void addListener(String className) {
  324. throw new UnsupportedOperationException();
  325. }
  326. @Override
  327. public <T extends EventListener> void addListener(T t) {
  328. throw new UnsupportedOperationException();
  329. }
  330. @Override
  331. public void addListener(Class<? extends EventListener> listenerClass) {
  332. throw new UnsupportedOperationException();
  333. }
  334. @Override
  335. public <T extends EventListener> T createListener(Class<T> clazz) {
  336. throw new UnsupportedOperationException();
  337. }
  338. }