View Javadoc

1   /*
2    * $Header: /cvsroot/jdbforms/dbforms/src/org/dbforms/util/PageContextBuffer.java,v 1.10 2005/02/19 21:26:32 hkollmann Exp $
3    * $Revision: 1.10 $
4    * $Date: 2005/02/19 21:26:32 $
5    *
6    * DbForms - a Rapid Application Development Framework
7    * Copyright (C) 2001 Joachim Peer <joepeer@excite.com>
8    *
9    * This library is free software; you can redistribute it and/or
10   * modify it under the terms of the GNU Lesser General Public
11   * License as published by the Free Software Foundation; either
12   * version 2.1 of the License, or (at your option) any later version.
13   *
14   * This library is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17   * Lesser General Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser General Public
20   * License along with this library; if not, write to the Free Software
21   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
22   */
23  
24  /*
25   * $Header: /cvsroot/jdbforms/dbforms/src/org/dbforms/util/PageContextBuffer.java,v 1.10 2005/02/19 21:26:32 hkollmann Exp $
26   * $Revision: 1.10 $
27   * $Date: 2005/02/19 21:26:32 $
28   *
29   */
30  package org.dbforms.util;
31  
32  import java.io.BufferedReader;
33  import java.io.IOException;
34  import java.io.InputStream;
35  import java.io.InputStreamReader;
36  
37  import java.util.Enumeration;
38  import java.util.Hashtable;
39  
40  import javax.servlet.RequestDispatcher;
41  
42  /***
43   * 
44   * read only PageContext.
45   * 
46   * Used to generate a form via doStart internally to use the results.
47   * 
48   * See StartReportServlet.
49   * 
50   */
51  import javax.servlet.Servlet;
52  import javax.servlet.ServletConfig;
53  import javax.servlet.ServletContext;
54  import javax.servlet.ServletException;
55  import javax.servlet.ServletRequest;
56  import javax.servlet.ServletResponse;
57  import javax.servlet.http.HttpServletRequest;
58  import javax.servlet.http.HttpSession;
59  import javax.servlet.jsp.JspException;
60  import javax.servlet.jsp.JspWriter;
61  import javax.servlet.jsp.PageContext;
62  
63  /***
64   * DOCUMENT ME!
65   * 
66   * @author $author$
67   * @version $Revision: 1.10 $
68   */
69  public class PageContextBuffer extends PageContext {
70  	private Exception exception;
71  
72  	/***
73  	 * Provides programmatic access to the ExpressionEvaluator. The JSP
74  	 * Container must return a valid instance of an ExpressionEvaluator that can
75  	 * parse EL expressions.
76  	 */
77  
78  	// The expression evaluator, for evaluating EL expressions.
79  	private org.apache.commons.el.ExpressionEvaluatorImpl elExprEval = new org.apache.commons.el.ExpressionEvaluatorImpl();
80  
81  	private Hashtable nametable;
82  
83  	private HttpSession session;
84  
85  	private JspWriterBuffer out;
86  
87  	private Servlet servlet;
88  
89  	private ServletConfig servletConfig;
90  
91  	private ServletContext servletContext;
92  
93  	private ServletRequest request;
94  
95  	private ServletResponse response;
96  
97  	private String errorPageURL;
98  
99  	// The variable resolver, for evaluating EL expressions.
100 	private org.apache.commons.el.VariableResolverImpl variableResolver = new org.apache.commons.el.VariableResolverImpl(
101 			this);
102 
103 	private boolean needsSession;
104 
105 	/***
106 	 * Creates a new PageContextDummy object.
107 	 */
108 	public PageContextBuffer() {
109 	}
110 
111 	/***
112 	 * DOCUMENT ME!
113 	 * 
114 	 * @param name
115 	 *            DOCUMENT ME!
116 	 * @param attribute
117 	 *            DOCUMENT ME!
118 	 */
119 	public void setAttribute(String name, Object attribute) {
120 		if ((name == null) || (attribute == null)) {
121 			throw new NullPointerException();
122 		}
123 
124 		nametable.put(name, attribute);
125 	}
126 
127 	/***
128 	 * DOCUMENT ME!
129 	 * 
130 	 * @param name
131 	 *            DOCUMENT ME!
132 	 * @param attribute
133 	 *            DOCUMENT ME!
134 	 * @param scope
135 	 *            DOCUMENT ME!
136 	 */
137 	public void setAttribute(String name, Object attribute, int scope) {
138 		if ((name == null) || (attribute == null)) {
139 			throw new NullPointerException();
140 		}
141 
142 		switch (scope) {
143 		case APPLICATION_SCOPE:
144 			break;
145 
146 		case PAGE_SCOPE:
147 			setAttribute(name, attribute);
148 
149 			break;
150 
151 		case REQUEST_SCOPE:
152 			break;
153 
154 		case SESSION_SCOPE:
155 
156 			if (!needsSession) {
157 				throw new IllegalArgumentException(
158 						"Invalid scope - Page does not participate in a session");
159 			}
160 
161 			break;
162 
163 		default:
164 			throw new IllegalArgumentException("Invalid scope");
165 		}
166 	}
167 
168 	/***
169 	 * DOCUMENT ME!
170 	 * 
171 	 * @param name
172 	 *            DOCUMENT ME!
173 	 * 
174 	 * @return DOCUMENT ME!
175 	 */
176 	public Object getAttribute(String name) {
177 		if (name == null) {
178 			throw new IllegalArgumentException();
179 		}
180 
181 		return (nametable.get(name));
182 	}
183 
184 	/***
185 	 * DOCUMENT ME!
186 	 * 
187 	 * @param name
188 	 *            DOCUMENT ME!
189 	 * @param scope
190 	 *            DOCUMENT ME!
191 	 * 
192 	 * @return DOCUMENT ME!
193 	 */
194 	public Object getAttribute(String name, int scope) {
195 		Object obj = null;
196 
197 		if (name == null) {
198 			throw new NullPointerException();
199 		}
200 
201 		switch (scope) {
202 		case PAGE_SCOPE:
203 			obj = getAttribute(name);
204 
205 			break;
206 
207 		case REQUEST_SCOPE:
208 			obj = request.getAttribute(name);
209 
210 			break;
211 
212 		case SESSION_SCOPE:
213 
214 			if (needsSession) {
215 				/* Throws IllegalStateException */
216 				obj = session.getAttribute(name);
217 			} else {
218 				throw new IllegalArgumentException(
219 						"Invalid scope - Page does not participate in a session");
220 			}
221 
222 			break;
223 
224 		case APPLICATION_SCOPE:
225 			obj = servletContext.getAttribute(name);
226 
227 			break;
228 
229 		default:
230 			throw new IllegalArgumentException("Invalid scope");
231 		}
232 
233 		return obj;
234 	}
235 
236 	/***
237 	 * DOCUMENT ME!
238 	 * 
239 	 * @param scope
240 	 *            DOCUMENT ME!
241 	 * 
242 	 * @return DOCUMENT ME!
243 	 */
244 	public Enumeration getAttributeNamesInScope(int scope) {
245 		switch (scope) {
246 		case PAGE_SCOPE:
247 			return nametable.keys();
248 
249 		case REQUEST_SCOPE:
250 			return request.getAttributeNames();
251 
252 		case SESSION_SCOPE:
253 
254 			if (!needsSession) {
255 				throw new IllegalArgumentException(
256 						"Invalid scope - Page does not participate in a session");
257 			}
258 			/* HttpSession should have get/setAttributeNames too :) */
259 			return session.getAttributeNames();
260 
261 		case APPLICATION_SCOPE:
262 			return servletContext.getAttributeNames();
263 
264 		default:
265 			throw new IllegalArgumentException("Invalid scope");
266 		}
267 	}
268 
269 	/***
270 	 * DOCUMENT ME!
271 	 * 
272 	 * @param name
273 	 *            DOCUMENT ME!
274 	 * 
275 	 * @return DOCUMENT ME!
276 	 */
277 	public int getAttributesScope(String name) {
278 		int scope = 0;
279 
280 		/* Search order - page, request, session (if supported), appl */
281 		if (getAttribute(name, PAGE_SCOPE) != null) {
282 			scope = PAGE_SCOPE;
283 		}
284 
285 		if (getAttribute(name, REQUEST_SCOPE) != null) {
286 			scope = REQUEST_SCOPE;
287 		}
288 
289 		if (needsSession) {
290 			if (getAttribute(name, SESSION_SCOPE) != null) {
291 				scope = SESSION_SCOPE;
292 			}
293 		}
294 
295 		if (getAttribute(name, APPLICATION_SCOPE) != null) {
296 			scope = APPLICATION_SCOPE;
297 		}
298 
299 		return scope;
300 	}
301 
302 	/***
303 	 * DOCUMENT ME!
304 	 * 
305 	 * @return DOCUMENT ME!
306 	 */
307 	public StringBuffer getBuffer() {
308 		return out.getBuffer();
309 	}
310 
311 	/***
312 	 * DOCUMENT ME!
313 	 * 
314 	 * @return DOCUMENT ME!
315 	 */
316 	public Exception getException() {
317 		return exception;
318 	}
319 
320 	/***
321 	 * DOCUMENT ME!
322 	 * 
323 	 * @return DOCUMENT ME!
324 	 */
325 	public javax.servlet.jsp.el.ExpressionEvaluator getExpressionEvaluator() {
326 		return elExprEval;
327 	}
328 
329 	/***
330 	 * DOCUMENT ME!
331 	 * 
332 	 * @return DOCUMENT ME!
333 	 */
334 	public JspWriter getOut() {
335 		return out;
336 	}
337 
338 	/***
339 	 * DOCUMENT ME!
340 	 * 
341 	 * @return DOCUMENT ME!
342 	 */
343 	public Object getPage() {
344 		return servlet;
345 	}
346 
347 	/***
348 	 * DOCUMENT ME!
349 	 * 
350 	 * @return DOCUMENT ME!
351 	 */
352 	public ServletRequest getRequest() {
353 		return request;
354 	}
355 
356 	/***
357 	 * DOCUMENT ME!
358 	 * 
359 	 * @return DOCUMENT ME!
360 	 */
361 	public ServletResponse getResponse() {
362 		return response;
363 	}
364 
365 	/***
366 	 * DOCUMENT ME!
367 	 * 
368 	 * @return DOCUMENT ME!
369 	 */
370 	public String getResult() {
371 		return out.getResult();
372 	}
373 
374 	/***
375 	 * DOCUMENT ME!
376 	 * 
377 	 * @return DOCUMENT ME!
378 	 */
379 	public ServletConfig getServletConfig() {
380 		return servletConfig;
381 	}
382 
383 	/***
384 	 * DOCUMENT ME!
385 	 * 
386 	 * @return DOCUMENT ME!
387 	 */
388 	public ServletContext getServletContext() {
389 		return servletContext;
390 	}
391 
392 	/***
393 	 * DOCUMENT ME!
394 	 * 
395 	 * @return DOCUMENT ME!
396 	 */
397 	public HttpSession getSession() {
398 		return session;
399 	}
400 
401 	/***
402 	 * DOCUMENT ME!
403 	 * 
404 	 * @return DOCUMENT ME!
405 	 */
406 	public javax.servlet.jsp.el.VariableResolver getVariableResolver() {
407 		return variableResolver;
408 	}
409 
410 	/***
411 	 * DOCUMENT ME!
412 	 * 
413 	 * @param name
414 	 *            DOCUMENT ME!
415 	 * 
416 	 * @return DOCUMENT ME!
417 	 */
418 	public Object findAttribute(String name) {
419 		Object obj = null;
420 
421 		/* Search order - page, request, session (if supported), appl */
422 		if ((obj = getAttribute(name, PAGE_SCOPE)) != null) {
423 			return obj;
424 		}
425 
426 		if ((obj = getAttribute(name, REQUEST_SCOPE)) != null) {
427 			return obj;
428 		}
429 
430 		if (needsSession) {
431 			if ((obj = getAttribute(name, SESSION_SCOPE)) != null) {
432 				return obj;
433 			}
434 		}
435 
436 		if ((obj = getAttribute(name, APPLICATION_SCOPE)) != null) {
437 			return obj;
438 		}
439 
440 		return obj;
441 	}
442 
443 	/***
444 	 * DOCUMENT ME!
445 	 * 
446 	 * @param relativeURLPath
447 	 *            DOCUMENT ME!
448 	 * 
449 	 * @throws ServletException
450 	 *             DOCUMENT ME!
451 	 * @throws IOException
452 	 *             DOCUMENT ME!
453 	 */
454 	public void forward(String relativeURLPath) throws ServletException,
455 			IOException {
456 		if (relativeURLPath == null) {
457 			throw new ServletException(
458 					"[PageContext.forward()] Got 'null' URL - Probably caused "
459 							+ "by a non-existent Request Time Attribute Value.");
460 		}
461 
462 		String path = decodePath(relativeURLPath);
463 
464 		RequestDispatcher requestDispatcher = servletContext
465 				.getRequestDispatcher(path);
466 
467 		requestDispatcher.forward(request, response);
468 	}
469 
470 	/***
471 	 * DOCUMENT ME!
472 	 * 
473 	 * @param t
474 	 *            DOCUMENT ME!
475 	 * 
476 	 * @throws IOException
477 	 *             DOCUMENT ME!
478 	 * @throws ServletException
479 	 *             DOCUMENT ME!
480 	 */
481 	public void handlePageException(Throwable t) throws IOException,
482 			ServletException {
483 		// set the request attribute with the Throwable.
484 		request.setAttribute("javax.servlet.jsp.jspException", t);
485 
486 		if ((errorPageURL != null) && !errorPageURL.equals("")) {
487 			try {
488 				forward(errorPageURL);
489 			} catch (IllegalStateException ise) {
490 				include(errorPageURL);
491 			}
492 		} else {
493 			// Otherwise throw the exception wrapped inside a ServletException.
494 			// Set the exception as the root cause in the ServletException
495 			// to get a stack trace for the real problem
496 			if (t instanceof IOException) {
497 				throw (IOException) t;
498 			}
499 
500 			if (t instanceof ServletException) {
501 				throw (ServletException) t;
502 			}
503 
504 			if (t instanceof RuntimeException) {
505 				throw (RuntimeException) t;
506 			}
507 
508 			if (t instanceof JspException) {
509 				Throwable rootCause = ((JspException) t).getRootCause();
510 
511 				if (rootCause != null) {
512 					throw new ServletException(t.getMessage(), rootCause);
513 				}
514 				throw new ServletException(t);
515 			}
516 
517 			throw new ServletException(t);
518 		}
519 	}
520 
521 	/***
522 	 * DOCUMENT ME!
523 	 * 
524 	 * @param e
525 	 *            DOCUMENT ME!
526 	 * 
527 	 * @throws ServletException
528 	 *             DOCUMENT ME!
529 	 * @throws IOException
530 	 *             DOCUMENT ME!
531 	 */
532 	public void handlePageException(Exception e) throws ServletException,
533 			IOException {
534 		// System.out.println("[PageContext] handling page exception");
535 		// e.printStackTrace();
536 		if (!errorPageURL.equals("")) {
537 			setAttribute(EXCEPTION, e, REQUEST_SCOPE);
538 			forward(errorPageURL);
539 		} else {
540 			System.out.println("Unhandled Page Exception:");
541 			e.printStackTrace();
542 			throw new ServletException("An unhandled Page Exception occurred");
543 		}
544 	}
545 
546 	/***
547 	 * DOCUMENT ME!
548 	 * 
549 	 * @param relativeURLPath
550 	 *            DOCUMENT ME!
551 	 * 
552 	 * @throws ServletException
553 	 *             DOCUMENT ME!
554 	 * @throws IOException
555 	 *             DOCUMENT ME!
556 	 */
557 	public void include(String relativeURLPath) throws ServletException,
558 			IOException {
559 		if (relativeURLPath == null) {
560 			throw new ServletException(
561 					"[PageContext.include()] Got 'null' URL. Probably caused "
562 							+ " by a non-existent Request Time Attribute Value.");
563 		}
564 
565 		out.flush();
566 
567 		String path = decodePath(relativeURLPath);
568 		RequestDispatcher requestDispatcher = servletContext
569 				.getRequestDispatcher(path);
570 
571 		if (requestDispatcher == null) {
572 			InputStream is = servletContext
573 					.getResourceAsStream(relativeURLPath);
574 
575 			if (is == null) {
576 				throw new ServletException(
577 						"[PageContext.include()] Unable to obtain include resource "
578 								+ relativeURLPath);
579 			}
580 
581 			BufferedReader in = new BufferedReader(new InputStreamReader(is));
582 
583 			try {
584 				int c;
585 
586 				while ((c = in.read()) > 0) {
587 					out.write(c);
588 				}
589 			} finally {
590 				in.close();
591 			}
592 		} else {
593 			HttpServletRequest httpReq = (HttpServletRequest) request;
594 
595 			/* Set additional attributes for include */
596 			String attrib;
597 
598 			if ((attrib = httpReq.getRequestURI()) != null) {
599 				request.setAttribute("javax.servlet.include.request_uri",
600 						attrib);
601 			}
602 
603 			if ((attrib = httpReq.getServletPath()) != null) {
604 				request.setAttribute("javax.servlet.include.servlet_path",
605 						attrib);
606 			}
607 
608 			if ((attrib = httpReq.getPathInfo()) != null) {
609 				request.setAttribute("javax.servlet.include.path_info", attrib);
610 			}
611 
612 			if ((attrib = httpReq.getQueryString()) != null) {
613 				request.setAttribute("javax.servlet.include.query_string",
614 						attrib);
615 			}
616 
617 			requestDispatcher.include(request, response);
618 		}
619 	}
620 
621 	/***
622 	 * DOCUMENT ME!
623 	 * 
624 	 * @param relativeURLPath
625 	 *            DOCUMENT ME!
626 	 * @param flush
627 	 *            DOCUMENT ME!
628 	 * 
629 	 * @throws ServletException
630 	 *             DOCUMENT ME!
631 	 * @throws IOException
632 	 *             DOCUMENT ME!
633 	 */
634 	public void include(String relativeURLPath, boolean flush)
635 			throws ServletException, IOException {
636 		include(relativeURLPath);
637 		out.flush();
638 	}
639 
640 	/***
641 	 * DOCUMENT ME!
642 	 * 
643 	 * @param servlet
644 	 *            DOCUMENT ME!
645 	 * @param request
646 	 *            DOCUMENT ME!
647 	 * @param response
648 	 *            DOCUMENT ME!
649 	 * @param errorPageURL
650 	 *            DOCUMENT ME!
651 	 * @param needsSession
652 	 *            DOCUMENT ME!
653 	 * @param bufferSize
654 	 *            DOCUMENT ME!
655 	 * @param autoFlush
656 	 *            DOCUMENT ME!
657 	 */
658 	public void initialize(Servlet aservlet, ServletRequest arequest,
659 			ServletResponse aresponse, String aerrorPageURL,
660 			boolean aneedsSession, int bufferSize, boolean autoFlush) {
661 		this.servlet = aservlet;
662 		this.request = arequest;
663 		this.response = aresponse;
664 		this.errorPageURL = aerrorPageURL;
665 		this.needsSession = aneedsSession;
666 
667 		if (needsSession) {
668 			session = ((HttpServletRequest) request).getSession();
669 		}
670 
671 		nametable = new Hashtable();
672 		out = new JspWriterBuffer(bufferSize, autoFlush, response);
673 		exception = null;
674 
675 		servletConfig = servlet.getServletConfig();
676 		servletContext = servletConfig.getServletContext();
677 	}
678 
679 	/***
680 	 * DOCUMENT ME!
681 	 */
682 	public void release() {
683 		this.servlet = null;
684 		this.request = null;
685 		this.response = null;
686 		this.errorPageURL = null;
687 
688 		nametable = null;
689 		out = null;
690 		exception = null;
691 
692 		servletConfig = null;
693 		servletContext = null;
694 	}
695 
696 	/***
697 	 * DOCUMENT ME!
698 	 * 
699 	 * @param name
700 	 *            DOCUMENT ME!
701 	 */
702 	public void removeAttribute(String name) {
703 		nametable.remove(name);
704 	}
705 
706 	/***
707 	 * DOCUMENT ME!
708 	 * 
709 	 * @param name
710 	 *            DOCUMENT ME!
711 	 * @param scope
712 	 *            DOCUMENT ME!
713 	 */
714 	public void removeAttribute(String name, int scope) {
715 		switch (scope) {
716 		case PAGE_SCOPE:
717 			break;
718 
719 		case REQUEST_SCOPE:
720 			throw new IllegalArgumentException(
721 					"Invalid scope - Can't remove attribute from REQUEST_SCOPE");
722 
723 		case SESSION_SCOPE:
724 
725 			if (!needsSession) {
726 				throw new IllegalArgumentException(
727 						"Invalid Scope - Page does not participate in an HTTP session");
728 			}
729 
730 			break;
731 
732 		case APPLICATION_SCOPE:
733 			break;
734 
735 		default:
736 			throw new IllegalArgumentException("Invalid Scope");
737 		}
738 	}
739 
740 	private String decodePath(String relativeURLPath) {
741 		String path;
742 
743 		if (relativeURLPath.startsWith("/")) {
744 			path = relativeURLPath;
745 		} else {
746 			path = ((HttpServletRequest) request).getServletPath();
747 			path = path.substring(0, path.lastIndexOf("/"));
748 			path = path + "/" + relativeURLPath;
749 		}
750 
751 		// System.out.println("[PageContext] Decoded path : " + path + "");
752 		return path;
753 	}
754 }