View Javadoc

1   package com.atlassian.johnson.filters;
2   
3   import com.atlassian.johnson.JohnsonEventContainer;
4   import com.atlassian.johnson.config.JohnsonConfig;
5   import com.atlassian.johnson.event.RequestEventCheck;
6   import com.atlassian.johnson.event.Event;
7   import com.atlassian.johnson.setup.SetupConfig;
8   
9   import javax.servlet.*;
10  import javax.servlet.http.HttpServletRequest;
11  import javax.servlet.http.HttpServletResponse;
12  import java.io.IOException;
13  import java.util.Iterator;
14  import java.util.Collection;
15  
16  /**
17   * Base class for handling error cases where the application is unavailable to handle normal requests.
18   */
19  public abstract class AbstractJohnsonFilter implements Filter
20  {
21      protected static final String TEXT_XML_UTF8_CONTENT_TYPE = "text/xml;charset=utf-8";
22  
23      protected FilterConfig filterConfig = null;
24      protected JohnsonConfig config;
25  
26      public void init(FilterConfig filterConfig)
27      {
28          this.filterConfig = filterConfig;
29          config = JohnsonConfig.getInstance();
30      }
31  
32      /**
33       * This filter checks to see if there are any application consistency errors before any pages are accessed. If there are errors then a redirect to the errors page is made
34       */
35      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException
36      {
37          String alreadyFilteredKey = this.getClass().getName() + "_already_filtered";
38          if (servletRequest.getAttribute(alreadyFilteredKey) != null)
39          {
40              filterChain.doFilter(servletRequest, servletResponse);
41              return;
42          }
43          else
44          {
45              servletRequest.setAttribute(alreadyFilteredKey, Boolean.TRUE);
46          }
47  
48          HttpServletRequest req = (HttpServletRequest) servletRequest;
49          HttpServletResponse resp = (HttpServletResponse) servletResponse;
50  
51          //get the URI of this request
52          String servletPath = getServletPath(req);
53  
54          //Get the container for this context and run all of the configured request event checks
55          JohnsonEventContainer appEventContainer = getContainerAndRunEventChecks(req);
56  
57          SetupConfig setup = config.getSetupConfig();
58  
59          //if there are application consistency events then redirect to the errors page
60          if (appEventContainer.hasEvents() && !ignoreURI(servletPath))
61          {
62              handleError(appEventContainer, req, resp);
63          }
64          //if application is not setup then send to the Setup Page
65          else if (!ignoreURI(servletPath) && !setup.isSetup() && !setup.isSetupPage(servletPath))
66          {
67              handleNotSetup(req, resp);
68          }
69          else
70          {
71              filterChain.doFilter(servletRequest, servletResponse);
72          }
73      }
74  
75      /**
76       * Handles the given request for error cases when there is a Johnson {@link com.atlassian.johnson.event.Event} which
77       * stops normal application functioning.
78       * @param appEventContainer the JohnsonEventContainer that contains the events.
79       * @param servletRequest the request being directed to the error.
80       * @param servletResponse the response.
81       * @throws IOException when the error cannot be handled.
82       */
83      protected abstract void handleError(JohnsonEventContainer appEventContainer, HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws IOException;
84  
85      /**
86       * Handles the given request for cases when the application is not yet setup which
87       * stops normal application functioning.
88       * @param servletRequest the request being directed to the error.
89       * @param servletResponse the response.
90       * @throws IOException when the error cannot be handled.
91       */
92      protected abstract void handleNotSetup(HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws IOException;
93  
94      protected boolean ignoreURI(String uri)
95      {
96          return uri.equalsIgnoreCase(config.getErrorPath()) || config.isIgnoredPath(uri);
97      }
98  
99      /**
100      * Retrieves the current request servlet path. Deals with differences between servlet specs (2.2 vs 2.3+)
101      *
102      * Taken from the Webwork RequestUtils class
103      *
104      * @param request the request
105      * @return the servlet path
106      */
107     protected static String getServletPath(HttpServletRequest request)
108     {
109         String servletPath = request.getServletPath();
110 
111         if (null != servletPath && !"".equals(servletPath))
112         {
113             return servletPath;
114         }
115 
116         String requestUri = request.getRequestURI();
117         int startIndex = request.getContextPath().equals("") ? 0 : request.getContextPath().length();
118         int endIndex = request.getPathInfo() == null ? requestUri.length() : requestUri.lastIndexOf(request.getPathInfo());
119 
120         if (startIndex > endIndex)
121         { // this should not happen
122             endIndex = startIndex;
123         }
124 
125         return requestUri.substring(startIndex, endIndex);
126     }
127 
128     protected JohnsonEventContainer getContainerAndRunEventChecks(HttpServletRequest req)
129     {
130         //Get the container for this context
131         JohnsonEventContainer appEventContainer = JohnsonEventContainer.get(filterConfig.getServletContext());
132         // run all of the configured request event checks
133         for (Iterator iterator = config.getRequestEventChecks().iterator(); iterator.hasNext();)
134         {
135             RequestEventCheck requestEventCheck = (RequestEventCheck) iterator.next();
136             requestEventCheck.check(appEventContainer, req);
137         }
138         return appEventContainer;
139     }
140 
141     protected String getStringForEvents(Collection events)
142     {
143         StringBuffer message = new StringBuffer();
144         int i = 1;
145         for (Iterator iterator = events.iterator(); iterator.hasNext(); i++)
146         {
147             Event event = (Event) iterator.next();
148             message.append(event.getDesc());
149             if(i < events.size())
150             {
151                 message.append("\n");
152             }
153         }
154         return message.toString();
155     }
156 
157     public void destroy()
158     {
159     }
160 }