KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tonbeller > wcf > controller > RequestFilter


1 /*
2  * ====================================================================
3  * This software is subject to the terms of the Common Public License
4  * Agreement, available at the following URL:
5  * http://www.opensource.org/licenses/cpl.html .
6  * Copyright (C) 2003-2004 TONBELLER AG.
7  * All Rights Reserved.
8  * You must accept the terms of that agreement to use this software.
9  * ====================================================================
10  *
11  *
12  */

13 package com.tonbeller.wcf.controller;
14
15 import java.io.IOException JavaDoc;
16 import java.io.PrintWriter JavaDoc;
17
18 import javax.servlet.Filter JavaDoc;
19 import javax.servlet.FilterChain JavaDoc;
20 import javax.servlet.FilterConfig JavaDoc;
21 import javax.servlet.ServletException JavaDoc;
22 import javax.servlet.ServletRequest JavaDoc;
23 import javax.servlet.ServletResponse JavaDoc;
24 import javax.servlet.http.HttpServletRequest JavaDoc;
25 import javax.servlet.http.HttpServletResponse JavaDoc;
26 import javax.servlet.http.HttpSession JavaDoc;
27 import javax.servlet.jsp.jstl.core.Config;
28
29 import org.apache.log4j.Logger;
30 import org.apache.log4j.MDC;
31
32 import com.tonbeller.tbutils.testenv.Environment;
33 import com.tonbeller.wcf.utils.DomUtils;
34 import com.tonbeller.wcf.utils.JDK13Utils;
35 import com.tonbeller.wcf.utils.UrlUtils;
36
37 /**
38  * Informs <code>RequestListeners</code> of incoming request. If a nextView attribute is present
39  * in the current request, it will forward to that. Otherwise the filter chain is executed.
40  */

41
42 public class RequestFilter implements Filter JavaDoc {
43
44   private static Logger logger = Logger.getLogger(RequestFilter.class);
45
46   static final String JavaDoc NEXTVIEW = RequestFilter.class.getName() + ".nextview";
47   static final String JavaDoc ISNEW = RequestFilter.class.getName() + ".isnew";
48
49   /** Name of the Request Attribute containing the Request.getRequestURI */
50   public static final String JavaDoc CONTEXT = "context";
51
52   /** if the session attribute FORCE_INDEX_JSP exists, then the client will be redirected to index.jsp */
53   public static final String JavaDoc FORCE_INDEX_JSP = "com.tonbeller.wcf.controller.FORCE_INDEX_JSP";
54
55   /**
56    * If this request parameter is present, the DomUtils.randomId()
57    * will be reset once.
58    */

59   public static final String JavaDoc RESET_RANDOM_SEED = "resetRandomSeed";
60
61   private String JavaDoc errorJSP = null;
62   private String JavaDoc busyJSP = null;
63   private String JavaDoc indexJSP = null;
64   private String JavaDoc[] passThru = null;
65
66   private String JavaDoc forceExtension = null;
67
68   public RequestFilter() {
69   }
70
71   public void init(FilterConfig JavaDoc config) throws ServletException JavaDoc {
72     errorJSP = config.getInitParameter("errorJSP");
73     forceExtension = config.getInitParameter("forceExtension");
74     indexJSP = config.getInitParameter("indexJSP");
75     busyJSP = config.getInitParameter("busyJSP");
76
77     String JavaDoc patternList = config.getInitParameter("passThru");
78     passThru = UrlUtils.parseUrlPatternList(patternList);
79   }
80
81   class MyHandler implements RequestSynchronizer.Handler {
82     protected RequestContext context;
83     protected HttpServletRequest JavaDoc request;
84     protected HttpServletResponse JavaDoc response;
85     protected FilterChain JavaDoc filterChain;
86
87     public MyHandler(RequestContext context, FilterChain JavaDoc filterChain) {
88       this.context = context;
89       this.request = context.getRequest();
90       this.response = context.getResponse();
91       this.filterChain = filterChain;
92     }
93
94     public String JavaDoc getResultURI() {
95       // did the controller change the view?
96
String JavaDoc uri = (String JavaDoc) request.getAttribute(NEXTVIEW);
97       if (uri != null) {
98         uri = UrlUtils.forceExtension(uri, forceExtension);
99         uri = UrlUtils.redirectURI(request, uri);
100         return uri;
101       }
102
103       // no, redisplay the current request
104
return request.getRequestURI();
105     }
106
107     public void normalRequest() throws Exception JavaDoc {
108       HttpSession JavaDoc session = request.getSession(true);
109       try {
110
111         if (request.getParameter(RESET_RANDOM_SEED) != null)
112           DomUtils.setRandomSeed(123);
113
114         if (redirectToIndex())
115           return;
116
117         // fire events
118
Controller controller = WcfController.instance(session);
119         controller.request(context);
120
121         // someone has called sendRedirect() on the response?
122
if (response.containsHeader("Location"))
123           return;
124         // someone has called sendError() or sendRedirect() on the response?
125
if (context.isResponseComplete())
126           return;
127
128         // The current page is redisplayed unless there was an error
129
// in which case we go to the start page.
130
String JavaDoc uri = (String JavaDoc) request.getAttribute(NEXTVIEW);
131         if (session.getAttribute(FORCE_INDEX_JSP) != null) {
132           session.removeAttribute(FORCE_INDEX_JSP);
133           uri = indexJSP;
134         }
135
136         if (uri != null)
137           forward(uri);
138         else
139           filterChain.doFilter(request, response);
140       } catch (Exception JavaDoc e) {
141         handleException(e);
142       }
143     }
144
145     public void recursiveRequest() throws Exception JavaDoc {
146       try {
147         filterChain.doFilter(request, response);
148       } catch (Exception JavaDoc e) {
149         handleException(e);
150       }
151     }
152     
153     private void handleException(Exception JavaDoc e) throws Exception JavaDoc {
154       logger.error("exeption", e);
155       logger.error("cause", JDK13Utils.getCause(e));
156       
157       // avoid endless recursion in BEA (exception in error page)
158
if (isErrorPage())
159         throw e;
160       
161       if (errorJSP != null) {
162         try {
163           logger.info("redirecting to error page " + errorJSP);
164           request.setAttribute("javax.servlet.jsp.jspException", e);
165           request.getRequestDispatcher(errorJSP).forward(request, response);
166         } catch (Exception JavaDoc e2) {
167           // there was an error displaying the error page. We
168
// ignore the second error and display the original error
169
// instead
170
throw e;
171         }
172       } else
173         throw e;
174     }
175
176     public void showBusyPage(boolean redirect) throws Exception JavaDoc {
177       if (redirectToIndex())
178         return;
179       if (busyJSP != null) {
180         if (redirect)
181           forward(busyJSP);
182         else
183           filterChain.doFilter(request, response);
184       } else
185         throw new IllegalStateException JavaDoc("concurrent requests and no busy.jsp defined in web.xml");
186     }
187
188     public boolean isBusyPage() {
189       if (busyJSP == null)
190         return false;
191       return request.getRequestURI().endsWith(busyJSP);
192     }
193     
194     public boolean isErrorPage() {
195       if (errorJSP == null)
196         return false;
197       return request.getRequestURI().endsWith(errorJSP);
198     }
199
200     /**
201      * @param uri
202      * @throws IOException
203      */

204     private void forward(String JavaDoc uri) throws IOException JavaDoc {
205       uri = UrlUtils.redirectURI(request, uri);
206       uri = UrlUtils.forceExtension(uri, forceExtension);
207       if (logger.isInfoEnabled())
208         logger.info("redirecting to " + uri);
209       response.sendRedirect(uri);
210     }
211
212     /**
213      * true, if the current request was redirected to the index page
214      * because there is no valid session.
215      */

216     protected boolean redirectToIndex() throws Exception JavaDoc {
217       if (indexJSP != null) {
218         // do not redirect to index.jsp while testing
219
if (Environment.isTest())
220           return false;
221
222         HttpSession JavaDoc session = context.getSession();
223         boolean isNew = session.isNew();
224         if (!isNew)
225           isNew = !"false".equals(session.getAttribute(ISNEW));
226         if (isNew) {
227           session.setAttribute(ISNEW, "false");
228           forward(indexJSP);
229           return true;
230         }
231       }
232       return false;
233     }
234
235   }
236
237   public void doFilter(ServletRequest JavaDoc req, ServletResponse JavaDoc res, FilterChain JavaDoc chain)
238       throws IOException JavaDoc, ServletException JavaDoc {
239     MultiPartEnabledRequest request = new MultiPartEnabledRequest((HttpServletRequest JavaDoc) req);
240     HttpServletResponse JavaDoc response = (HttpServletResponse JavaDoc) res;
241
242     HttpSession JavaDoc session = request.getSession(true);
243     MDC.put("SessionID", session.getId());
244
245     String JavaDoc cpath = request.getContextPath();
246     request.setAttribute(CONTEXT, cpath);
247
248     RequestContext context = RequestContextFactoryFinder.createContext(request, response, true);
249     try {
250       // set locale for JSTL tags
251
Config.set(request, Config.FMT_LOCALE, context.getLocale());
252       // log if necessary
253
if (logger.isInfoEnabled())
254         logRequest(request);
255
256       if (passThru(req)) {
257         chain.doFilter(req, res);
258         return;
259       }
260
261       MyHandler handler = new MyHandler(context, chain);
262       long t1 = System.currentTimeMillis();
263       RequestSynchronizer.instance(request).handleRequest(handler);
264       long t2 = System.currentTimeMillis();
265       if (logger.isInfoEnabled())
266         logger.info("Request Execution total time: " + (t2 - t1) + " ms");
267     } catch (Throwable JavaDoc e) {
268       PrintWriter JavaDoc out = null;
269       try {
270         out = response.getWriter();
271       } catch (Exception JavaDoc e2) {
272         out = new PrintWriter JavaDoc(System.out);
273         logger.error("No output writer could be retrieved, logging to stdout");
274       }
275       out.println("<html><body>");
276       while (e != null) {
277         logger.error("Error handling request", e);
278         out.println();
279         out.println("<h2>" + e.toString() + "</h2><pre>");
280         e.printStackTrace(out);
281         out.println("</pre>");
282
283         Throwable JavaDoc prev = e;
284         e = JDK13Utils.getCause(e);
285         if (e == prev)
286           break;
287       }
288       out.println("</body></html>");
289     } finally {
290       context.invalidate();
291     }
292   }
293
294   private boolean passThru(ServletRequest JavaDoc req) {
295     if (passThru == null)
296       return false;
297     HttpServletRequest JavaDoc hsr = (HttpServletRequest JavaDoc) req;
298     return UrlUtils.matchPattern(hsr, passThru);
299   }
300
301   /** for testing */
302   void setForceExtension(String JavaDoc forceExtension) {
303     this.forceExtension = forceExtension;
304   }
305
306   private void logRequest(HttpServletRequest JavaDoc request) {
307     logger.info(">>> Request " + request.getScheme() + "://" + request.getServerName() + ":"
308         + request.getServerPort() + request.getContextPath() + request.getServletPath() + "["
309         + request.getPathInfo() + "]" + "[?" + request.getQueryString() + "]");
310   }
311
312   public static void setSessionIsNew(HttpSession JavaDoc session, boolean isNew) {
313     session.setAttribute(ISNEW, Boolean.toString(isNew));
314   }
315
316   public static void setForceIndexJsp(HttpSession JavaDoc session, boolean b) {
317     if (b)
318       session.setAttribute(FORCE_INDEX_JSP, "true");
319     else
320       session.removeAttribute(FORCE_INDEX_JSP);
321   }
322
323   public void destroy() {
324   }
325
326 }
Popular Tags