1   package com.atlassian.plugin.servlet;
2   
3   import com.atlassian.plugin.servlet.descriptors.ServletFilterModuleDescriptor;
4   import com.atlassian.plugin.servlet.descriptors.ServletModuleDescriptor;
5   import com.atlassian.plugin.servlet.filter.FilterLocation;
6   import com.atlassian.plugin.servlet.filter.ServletFilterModuleContainerFilter;
7   
8   import javax.servlet.Filter;
9   import javax.servlet.FilterConfig;
10  import javax.servlet.Servlet;
11  import javax.servlet.ServletConfig;
12  import javax.servlet.ServletContext;
13  import javax.servlet.ServletContextListener;
14  import javax.servlet.ServletException;
15  import javax.servlet.http.HttpServlet;
16  
17  /**
18   * The ServletModuleManager is responsible for servlets and filters - and their servlet contexts - defined in plugins.
19   * It is used by instances of the {@link ServletModuleContainerServlet} and {@link ServletFilterModuleContainerFilter}
20   * to lookup, create and wrap the filters and servlets defined in plugins.  
21   * <p/>
22   * When the first {@link Filter} or {@link Servlet} is first accessed in a plugin, a new {@link ServletContext} is
23   * created for all the modules in the plugin to share.  This is done by wrapping the applications 
24   * {@link ServletContext}, creating a map of attributes that are local to the plugin that are shadowed by the 
25   * applications {@link ServletContext} attributes, merging any servlet context init parameters from the plugin and the
26   * application, and then running through any {@link ServletContextListener}s defined by the plugin has calling their
27   * contextInitialized() methods. 
28   * <p/>
29   * The shadowing of the the plugins {@link ServletContext}s attributes are shadowed by the applications attributes 
30   * means that if an attribute does not exist in the plugin local attribute map, the applications attributes will be 
31   * returned.  The plugin is thereby prevented from modifying the base applications context attributes on an application
32   * wide scope and can instead only change them, but not remove them, on a local scope.  
33   * <p/>
34   * The init parameters in the plugin will override parameters from the base applications servlet
35   * init parameters that have the same name.
36   * <p/>
37   * During the creation of Filters and Servlets, the {@link FilterConfig} and {@link ServletConfig} provided to 
38   * Filters and Servlets contain the plugin local {@link ServletContext}, as described above, 
39   * and provides access to the init parameters defined in the plugin xml for the Filter or Servlet.   
40   * <p/>
41   * After being created, the filters and servlets are wrapped to ensure the the init(), service(), doFilter(), 
42   * and destroy() methods and other methods defined in the Filter and Servlet interfaces are executed in the plugins
43   * {@link ClassLoader}.
44   * <p/>
45   * The plugins {@link ServletContext} is not destroyed until the plugin is disabled.  It is also at this time that any
46   * {@link ServletContextListener}s will have their contextDestroyed() methods called.
47   */
48  public interface ServletModuleManager
49  {
50      /**
51       * Register a new servlet plugin module.
52       * 
53       * @param descriptor Details of what the servlet class is and the path it should serve.
54       */
55      void addServletModule(ServletModuleDescriptor descriptor);
56  
57      /**
58       * Return an instance of the HttpServlet that should be used to serve content matching the provided url path.
59       * 
60       * @param path Path of the incoming request to serve. 
61       * @param servletConfig ServletConfig given to the delegating servlet. 
62       * @return HttpServlet that has been registered to serve up content matching the passed in path.
63       * @throws ServletException Thrown if there is a problem initializing the servlet to be returned.
64       */
65      HttpServlet getServlet(String path, final ServletConfig servletConfig) throws ServletException;
66  
67      /**
68       * Remove a previously registered servlet plugin module.  Requests that come in on the path described in the 
69       * descriptor will no longer be served.
70       *  
71       * @param descriptor Details of what servlet module to remove.
72       */
73      void removeServletModule(ServletModuleDescriptor descriptor);
74  
75      /**
76       * Register a new filter plugin module.
77       * 
78       * @param descriptor Details of what the filter class is and the path it should serve.
79       */
80      void addFilterModule(ServletFilterModuleDescriptor descriptor);
81  
82      /**
83       * Returns the filters that have been registered to filter requests at the specified path matching the location 
84       * in the filter stack. 
85       * 
86       * @param location Place in the applications filter stack the filters should be applied.
87       * @param pathInfo Path of the incoming request to filter.
88       * @param filterConfig FilterConfig given to the delegating filter.
89       * @return List of filters to be applied, already sorted by weight
90       * @throws ServletException Thrown if there is a problem initializing one of the filters to apply.
91       */
92      Iterable<Filter> getFilters(FilterLocation location, String pathInfo, FilterConfig filterConfig) throws ServletException;
93  
94      /**
95       * Remove a previously registered filter plugin module.  Requests that come in on the path described in the 
96       * descriptor will no longer be served.
97       *  
98       * @param descriptor Details of what filter module to remove.
99       */
100     void removeFilterModule(ServletFilterModuleDescriptor descriptor);
101 }