KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > jsp > PageContextImpl


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source 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, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.jsp;
31
32 import com.caucho.el.EL;
33 import com.caucho.el.ExprEnv;
34 import com.caucho.jsp.cfg.JspPropertyGroup;
35 import com.caucho.jsp.el.ExpressionEvaluatorImpl;
36 import com.caucho.jsp.el.JspApplicationContextImpl;
37 import com.caucho.jsp.el.PageContextELResolver;
38 import com.caucho.jstl.JstlPageContext;
39 import com.caucho.log.Log;
40 import com.caucho.server.connection.AbstractHttpRequest;
41 import com.caucho.server.connection.AbstractResponseStream;
42 import com.caucho.server.connection.CauchoRequest;
43 import com.caucho.server.connection.CauchoResponse;
44 import com.caucho.server.connection.RequestAdapter;
45 import com.caucho.server.connection.ToCharResponseAdapter;
46 import com.caucho.server.webapp.RequestDispatcherImpl;
47 import com.caucho.server.webapp.WebApp;
48 import com.caucho.util.CharBuffer;
49 import com.caucho.util.HashMapImpl;
50 import com.caucho.util.L10N;
51 import com.caucho.util.NullEnumeration;
52 import com.caucho.vfs.ClientDisconnectException;
53 import com.caucho.vfs.FlushBuffer;
54 import com.caucho.vfs.Path;
55 import com.caucho.vfs.TempCharBuffer;
56 import com.caucho.xpath.VarEnv;
57
58 import org.w3c.dom.Node JavaDoc;
59
60 import javax.el.ELContext;
61 import javax.el.ELContextEvent;
62 import javax.el.ELContextListener;
63 import javax.el.ELResolver;
64 import javax.el.ValueExpression;
65 import javax.servlet.*;
66 import javax.servlet.http.Cookie JavaDoc;
67 import javax.servlet.http.HttpServletRequest JavaDoc;
68 import javax.servlet.http.HttpServletResponse JavaDoc;
69 import javax.servlet.http.HttpSession JavaDoc;
70 import javax.servlet.jsp.ErrorData JavaDoc;
71 import javax.servlet.jsp.JspContext JavaDoc;
72 import javax.servlet.jsp.JspException JavaDoc;
73 import javax.servlet.jsp.JspWriter JavaDoc;
74 import javax.servlet.jsp.PageContext JavaDoc;
75 import javax.servlet.jsp.SkipPageException JavaDoc;
76 import javax.servlet.jsp.el.ExpressionEvaluator JavaDoc;
77 import javax.servlet.jsp.el.VariableResolver JavaDoc;
78 import javax.servlet.jsp.jstl.core.Config;
79 import javax.servlet.jsp.jstl.fmt.LocalizationContext;
80 import javax.servlet.jsp.tagext.BodyContent JavaDoc;
81 import javax.servlet.jsp.tagext.JspFragment JavaDoc;
82 import java.io.FileNotFoundException JavaDoc;
83 import java.io.IOException JavaDoc;
84 import java.io.PrintWriter JavaDoc;
85 import java.io.Reader JavaDoc;
86 import java.io.Writer JavaDoc;
87 import java.lang.reflect.Method JavaDoc;
88 import java.text.MessageFormat JavaDoc;
89 import java.util.Collections JavaDoc;
90 import java.util.Enumeration JavaDoc;
91 import java.util.HashMap JavaDoc;
92 import java.util.Locale JavaDoc;
93 import java.util.Map JavaDoc;
94 import java.util.ResourceBundle JavaDoc;
95 import java.util.logging.Level JavaDoc;
96 import java.util.logging.Logger JavaDoc;
97
98 public class PageContextImpl extends PageContext
99   implements ExprEnv, JstlPageContext, VariableResolver JavaDoc {
100   private static final Logger JavaDoc log = Log.open(PageContextImpl.class);
101   static final L10N L = new L10N(PageContextImpl.class);
102   
103   private JspWriterAdapter _jspAdapter = new JspWriterAdapter();
104   private JspServletOutputStream _jspOutputStream =
105     new JspServletOutputStream(this);
106
107   private Map JavaDoc<String JavaDoc,Object JavaDoc> _attributes;
108   private Servlet _servlet;
109   private HttpServletRequest JavaDoc _request;
110
111   private CauchoResponse _response;
112   private ToCharResponseAdapter _responseAdapter;
113   
114   private WebApp _webApp;
115   private HttpSession JavaDoc _session;
116   private JspWriter JavaDoc _topOut;
117   private JspWriter JavaDoc _out;
118   private String JavaDoc _errorPage;
119   protected boolean _isFilled;
120   
121   private AbstractResponseStream _responseStream;
122
123   private BodyResponseStream _bodyResponseStream;
124   
125   private JspPrintWriter _jspPrintWriter;
126
127   private int _bufferSize = 8192;
128   private boolean autoFlush;
129   private BodyContentImpl _bodyOut;
130
131   private BundleManager _bundleManager;
132
133   private VarEnv _varEnv;
134   private Node JavaDoc _nodeEnv;
135
136   private final CharBuffer _cb = new CharBuffer();
137
138   private VariableResolver JavaDoc _varResolver;
139   private ELContext _elContext;
140   private ELResolver _elResolver;
141   private javax.el.FunctionMapper _functionMapper;
142   private javax.el.VariableMapper _variableMapper;
143   private boolean _hasException;
144
145   private HashMap JavaDoc<String JavaDoc,Method JavaDoc> _functionMap;
146
147   private ExpressionEvaluatorImpl _expressionEvaluator;
148
149   PageContextImpl()
150   {
151     _attributes = new HashMapImpl<String JavaDoc,Object JavaDoc>();
152     
153     _bodyResponseStream = new BodyResponseStream();
154     _bodyResponseStream.start();
155     
156     _jspPrintWriter = new JspPrintWriter();
157   }
158
159   public void initialize(Servlet servlet,
160              ServletRequest JavaDoc request,
161              ServletResponse JavaDoc response,
162              String JavaDoc errorPage,
163              boolean needsSession,
164              int bufferSize,
165              boolean autoFlush)
166   {
167     HttpSession JavaDoc session = null;
168     
169     if (needsSession)
170       session = ((HttpServletRequest JavaDoc) request).getSession(true);
171
172     ServletConfig config = servlet.getServletConfig();
173     WebApp app = (WebApp) config.getServletContext();
174
175     initialize(servlet, app, request, response,
176            errorPage, session, bufferSize, autoFlush,
177            false);
178   }
179
180   public void initialize(Servlet servlet,
181              WebApp app,
182              ServletRequest JavaDoc request,
183              ServletResponse JavaDoc response,
184              String JavaDoc errorPage,
185              HttpSession JavaDoc session,
186              int bufferSize,
187              boolean autoFlush,
188              boolean isPrintNullAsBlank)
189   {
190     _servlet = servlet;
191     _request = (HttpServletRequest JavaDoc) request;
192
193     if (response instanceof CauchoResponse
194     && bufferSize <= TempCharBuffer.SIZE) {
195       _response = (CauchoResponse) response;
196       _responseAdapter = null;
197     }
198     else {
199       // JSP.12.2.3 - JSP must use PrintWriter
200
_responseAdapter = ToCharResponseAdapter.create((HttpServletResponse JavaDoc) response);
201       _response = _responseAdapter;
202     }
203     
204     _responseStream = _response.getResponseStream();
205     _topOut = _jspAdapter;
206     _responseStream.setAutoFlush(autoFlush);
207     _jspAdapter.init(null, _responseStream);
208     _jspAdapter.setPrintNullAsBlank(isPrintNullAsBlank);
209
210     if (bufferSize != TempCharBuffer.SIZE) {
211       try {
212     _responseStream.setBufferSize(bufferSize);
213       } catch (Throwable JavaDoc e) {
214     log.log(Level.FINE, e.toString(), e);
215       }
216     }
217
218     // needed for includes from static pages
219

220     _bufferSize = bufferSize;
221     this.autoFlush = autoFlush;
222     _session = session;
223
224     _out = _topOut;
225     
226     _errorPage = errorPage;
227     _webApp = app;
228
229     //_topOut.init(this, bufferSize, autoFlush);
230

231     // jsp/17ee
232
//_jspPrintWriter.init(_topOut);
233
//_response.setPrintWriter(_jspPrintWriter);
234

235     // not quite correct
236
// _writerStreamImpl.setWriter(_topOut);
237
// _response.setPrintWriter(body.getWriter());
238

239     /*
240     _elContext = null;
241     _elResolver = null;
242     */

243
244     _hasException = false;
245     //if (_attributes.size() > 0)
246
// _attributes.clear();
247
_isFilled = false;
248     _bundleManager = null;
249     _varResolver = null;
250     _nodeEnv = null;
251
252     if (servlet instanceof Page) {
253       Page page = (Page) servlet;
254
255       _functionMap = page._caucho_getFunctionMap();
256     }
257     else
258       _functionMap = null;
259   }
260
261   protected void setOut(JspWriter JavaDoc out)
262   {
263     _out = out;
264   }
265
266   protected void clearAttributes()
267   {
268     _attributes.clear();
269   }
270
271   /**
272    * Returns the page attribute with the given name.
273    *
274    * @param name the attribute name.
275    *
276    * @return the attribute's value.
277    */

278   public Object JavaDoc getAttribute(String JavaDoc name)
279   {
280     if (name == null)
281       throw new NullPointerException JavaDoc(L.l("getAttribute must have a non-null name"));
282     
283     Object JavaDoc value = _attributes.get(name);
284     if (value != null)
285       return value;
286     else if (! _isFilled) {
287       fillAttribute();
288       value = _attributes.get(name);
289     }
290
291     if (value != null) {
292     }
293     else if (name.equals(OUT)) {
294       // jsp/162d
295
return _out;
296     }
297
298     return value;
299   }
300
301   /**
302    * Sets the page attribute with the given name.
303    *
304    * @param name the attribute name.
305    * @param value the new value
306    */

307   public void setAttribute(String JavaDoc name, Object JavaDoc attribute)
308   {
309     if (name == null)
310       throw new NullPointerException JavaDoc(L.l("setAttribute must have a non-null name"));
311     
312     if (attribute != null)
313       _attributes.put(name, attribute);
314     else
315       _attributes.remove(name);
316   }
317
318   /**
319    * Sets the page attribute with the given name.
320    *
321    * @param name the attribute name.
322    * @param value the new value
323    */

324   public Object JavaDoc putAttribute(String JavaDoc name, Object JavaDoc attribute)
325   {
326     if (name == null)
327       throw new NullPointerException JavaDoc(L.l("putAttribute must have a non-null name"));
328     
329     if (attribute != null)
330       return _attributes.put(name, attribute);
331     else
332       return _attributes.remove(name);
333   }
334
335   /**
336    * Removes a named attribute from the page context.
337    *
338    * @param name the name of the attribute to remove
339    */

340   public void removeAttribute(String JavaDoc name)
341   {
342     if (name == null)
343       throw new NullPointerException JavaDoc(L.l("removeAttribute must have a non-null name"));
344     
345     _attributes.remove(name);
346     // jsp/162b
347
if (_request != null)
348       _request.removeAttribute(name);
349
350     if (_session != null) {
351       try {
352     _session.removeAttribute(name);
353       } catch (IllegalStateException JavaDoc e) {
354     // jsp/162f
355
log.log(Level.FINE, e.toString(), e);
356       }
357     }
358     
359     if (_webApp != null)
360       _webApp.removeAttribute(name);
361   }
362
363   public Enumeration<String JavaDoc> getAttributeNames()
364   {
365     if (! _isFilled)
366       fillAttribute();
367
368     return Collections.enumeration(_attributes.keySet());
369   }
370
371   /**
372    * Fills the predefined page content _attributes with their values.
373    */

374   protected void fillAttribute()
375   {
376     _isFilled = true;
377     _attributes.put(PAGE, _servlet);
378     _attributes.put(PAGECONTEXT, this);
379     _attributes.put(REQUEST, getCauchoRequest());
380     _attributes.put(RESPONSE, getCauchoResponse());
381     if (_servlet != null)
382       _attributes.put(CONFIG, _servlet.getServletConfig());
383     if (getSession() != null)
384       _attributes.put(SESSION, getSession());
385     _attributes.put(APPLICATION, getApplication());
386   }
387
388   public Object JavaDoc getAttribute(String JavaDoc name, int scope)
389   {
390     switch (scope) {
391     case PAGE_SCOPE:
392       return getAttribute(name);
393     case REQUEST_SCOPE:
394       return getCauchoRequest().getAttribute(name);
395     case SESSION_SCOPE:
396       {
397     HttpSession JavaDoc session = getSession();
398     return session != null ? session.getValue(name) : null;
399       }
400     case APPLICATION_SCOPE:
401       return getApplication().getAttribute(name);
402
403     default:
404       throw new IllegalArgumentException JavaDoc();
405     }
406   }
407
408   public void setAttribute(String JavaDoc name, Object JavaDoc value, int scope)
409   {
410     switch (scope) {
411     case PAGE_SCOPE:
412       setAttribute(name, value);
413       break;
414
415     case REQUEST_SCOPE:
416       getCauchoRequest().setAttribute(name, value);
417       break;
418
419     case SESSION_SCOPE:
420       if (getSession() != null)
421         getSession().putValue(name, value);
422       break;
423
424     case APPLICATION_SCOPE:
425       getApplication().setAttribute(name, value);
426       break;
427
428     default:
429       throw new IllegalArgumentException JavaDoc();
430     }
431   }
432
433   public void removeAttribute(String JavaDoc name, int scope)
434   {
435     if (name == null)
436       throw new NullPointerException JavaDoc(L.l("removeAttribute must have a non-null name"));
437     
438     switch (scope) {
439     case PAGE_SCOPE:
440       if (name != null)
441     _attributes.remove(name);
442       break;
443
444     case REQUEST_SCOPE:
445       getCauchoRequest().removeAttribute(name);
446       break;
447
448     case SESSION_SCOPE:
449       if (getSession() != null)
450         getSession().removeValue(name);
451       break;
452
453     case APPLICATION_SCOPE:
454       getApplication().removeAttribute(name);
455       break;
456
457     default:
458       throw new IllegalArgumentException JavaDoc();
459     }
460   }
461
462   public Enumeration getAttributeNames(int scope)
463   {
464     switch (scope) {
465     case PAGE_SCOPE:
466       return getAttributeNames();
467
468     case REQUEST_SCOPE:
469       return getCauchoRequest().getAttributeNames();
470
471     case SESSION_SCOPE:
472       if (getSession() != null)
473         return new StringArrayEnum(getSession().getValueNames());
474       else
475         return NullEnumeration.create();
476
477     case APPLICATION_SCOPE:
478       return getApplication().getAttributeNames();
479
480     default:
481       throw new IllegalArgumentException JavaDoc();
482     }
483   }
484
485   public Enumeration getAttributeNamesInScope(int scope)
486   {
487     return getAttributeNames(scope);
488   }
489
490   /**
491    * Finds an attribute in any of the scopes from page to webApp.
492    *
493    * @param name the attribute name.
494    *
495    * @return the attribute value
496    */

497   public Object JavaDoc findAttribute(String JavaDoc name)
498   {
499     Object JavaDoc value;
500
501     if ((value = getAttribute(name)) != null)
502       return value;
503
504     if ((value = getCauchoRequest().getAttribute(name)) != null)
505       return value;
506
507     HttpSession JavaDoc session = getSession();
508     if (session != null) {
509       try {
510     value = session.getAttribute(name);
511       } catch (IllegalStateException JavaDoc e) {
512     // jsp/162e
513
log.log(Level.FINE, e.toString(), e);
514       }
515
516       if (value != null)
517     return value;
518     }
519
520     return getServletContext().getAttribute(name);
521   }
522
523   /**
524    * Return the scope of the named attribute.
525    *
526    * @param name the name of the attribute.
527    *
528    * @return the scope of the attribute
529    */

530   public int getAttributesScope(String JavaDoc name)
531   {
532     if (getAttribute(name) != null)
533       return PAGE_SCOPE;
534
535     if (getCauchoRequest().getAttribute(name) != null)
536       return REQUEST_SCOPE;
537
538     HttpSession JavaDoc session = getSession();
539     if (session != null && session.getValue(name) != null)
540       return SESSION_SCOPE;
541
542     if (getApplication().getAttribute(name) != null)
543       return APPLICATION_SCOPE;
544
545     return 0;
546   }
547
548   /**
549    * Sets the attribute map.
550    */

551   public Map JavaDoc<String JavaDoc,Object JavaDoc> setMap(Map JavaDoc<String JavaDoc,Object JavaDoc> map)
552   {
553     Map JavaDoc<String JavaDoc,Object JavaDoc> oldMap = _attributes;
554     _attributes = map;
555     return oldMap;
556   }
557
558   /**
559    * Returns the current writer.
560    */

561   public JspWriter JavaDoc getOut()
562   {
563     return _out;
564   }
565
566   /**
567    * Pushes a new BodyContent onto the JspWriter stack.
568    */

569   public BodyContent JavaDoc pushBody()
570   {
571     BodyContentImpl body;
572     if (_bodyOut != null) {
573       body = _bodyOut;
574       _bodyOut = null;
575     }
576     else
577       body = BodyContentImpl.allocate();
578
579     CauchoResponse response = getCauchoResponse();
580     
581     body.init(_out);
582     
583     _out = body;
584
585     response.setForbidForward(true);
586     try {
587       _bodyResponseStream.flushBuffer();
588     } catch (IOException JavaDoc e) {
589     }
590     _bodyResponseStream.start();
591     _bodyResponseStream.setWriter(body);
592     _bodyResponseStream.setEncoding(response.getCharacterEncoding());
593     response.setResponseStream(_bodyResponseStream);
594     
595     return body;
596   }
597
598   /**
599    * Pushes a new writer onto the JspWriter stack.
600    */

601   public JspWriter JavaDoc pushBody(Writer JavaDoc writer)
602   {
603     if (writer == _out)
604       return null;
605     
606     JspWriter JavaDoc oldWriter = _out;
607     
608     StreamJspWriter jspWriter;
609
610     jspWriter = new StreamJspWriter();
611     jspWriter.init(_out, writer);
612     
613     _out = jspWriter;
614
615     getCauchoResponse().setForbidForward(true);
616
617     _bodyResponseStream.setWriter(writer);
618     getCauchoResponse().setResponseStream(_bodyResponseStream);
619
620     return oldWriter;
621   }
622
623   /**
624    * Pops the BodyContent from the JspWriter stack.
625    *
626    * @return the enclosing writer
627    */

628   public JspWriter JavaDoc popBody()
629   {
630     BodyContentImpl bodyOut = (BodyContentImpl) _out;
631     _out = bodyOut.getEnclosingWriter();
632
633     try {
634       _bodyResponseStream.flushBuffer();
635       //if (_writeStream != null)
636
// _writeStream.flushBuffer();
637
} catch (IOException JavaDoc e) {
638       log.log(Level.WARNING, e.toString(), e);
639     }
640     
641     if (_out instanceof StreamJspWriter) {
642       StreamJspWriter writer = (StreamJspWriter) _out;
643
644       _bodyResponseStream.setWriter(writer.getWriter());
645     }
646     else if (_out instanceof JspWriterAdapter) {
647       if (getCauchoResponse() != null) {
648     getCauchoResponse().setResponseStream(_responseStream);
649     getCauchoResponse().setForbidForward(false);
650       }
651     }
652     else if (_out instanceof BodyContentImpl) {
653       BodyContentImpl body = (BodyContentImpl) _out;
654       
655       _bodyResponseStream.setWriter(body.getWriter());
656     }
657
658     return _out;
659   }
660
661   /**
662    * Pops the BodyContent from the JspWriter stack.
663    *
664    * @return the enclosing writer
665    */

666   public JspWriter JavaDoc popAndReleaseBody()
667     throws IOException JavaDoc
668   {
669     BodyContentImpl body = (BodyContentImpl) getOut();
670
671     JspWriter JavaDoc out = popBody();
672
673     releaseBody(body);
674
675     return out;
676   }
677
678   public void releaseBody(BodyContentImpl out)
679     throws IOException JavaDoc
680   {
681     if (_bodyOut == null) {
682       out.releaseNoFree();
683       _bodyOut = out;
684     }
685     else
686       out.release();
687   }
688
689   /**
690    * Pops the BodyContent from the JspWriter stack.
691    *
692    * @param oldWriter the old writer
693    */

694   public JspWriter JavaDoc setWriter(JspWriter JavaDoc oldWriter)
695   {
696     if (_out == oldWriter)
697       return oldWriter;
698
699     /*
700     if (_out instanceof FlushBuffer) {
701       try {
702     ((FlushBuffer) _out).flushBuffer();
703       } catch (IOException e) {
704       }
705     }
706     */

707     try {
708       if (_out instanceof FlushBuffer)
709     ((FlushBuffer) _out).flushBuffer();
710     } catch (IOException JavaDoc e) {
711     }
712     
713     _out = oldWriter;
714
715     // jsp/18eg
716
if (_out instanceof StreamJspWriter) {
717       StreamJspWriter writer = (StreamJspWriter) _out;
718
719       _bodyResponseStream.setWriter(writer.getWriter());
720     }
721     else if (_out instanceof JspWriterAdapter) {
722       if (getCauchoResponse() != null) {
723     getCauchoResponse().setResponseStream(_responseStream);
724     getCauchoResponse().setForbidForward(false);
725       }
726     }
727     else if (_out instanceof BodyContentImpl) {
728       BodyContentImpl body = (BodyContentImpl) _out;
729       
730       _bodyResponseStream.setWriter(body.getWriter());
731     }
732
733     return oldWriter;
734
735     // getCauchoResponse().setWriter(_os);
736
}
737
738   /**
739    * Returns the top writer.
740    */

741   public PrintWriter JavaDoc getTopWriter()
742     throws IOException JavaDoc
743   {
744     CauchoResponse response = getCauchoResponse();
745       
746     AbstractResponseStream currentStream = response.getResponseStream();
747     
748     response.setResponseStream(_responseStream);
749
750     try {
751       return response.getWriter();
752     } finally {
753       response.setResponseStream(currentStream);
754     }
755   }
756
757   /**
758    * Returns the response output stream.
759    */

760   ServletOutputStream getOutputStream()
761   {
762     try {
763       return getCauchoResponse().getOutputStream();
764     } catch (IOException JavaDoc e) {
765       throw new RuntimeException JavaDoc(e);
766     }
767   }
768
769   /**
770    * Returns the underlying servlet for the page.
771    */

772   public Object JavaDoc getPage()
773   {
774     return _servlet;
775   }
776
777   /**
778    * Returns the servlet request for the page.
779    */

780   public ServletRequest JavaDoc getRequest()
781   {
782     return _request;
783   }
784   
785   /**
786    * Returns the servlet response for the page.
787    */

788   public ServletResponse JavaDoc getResponse()
789   {
790     return getCauchoResponse();
791   }
792   
793   /**
794    * Returns the servlet response for the page.
795    */

796   public CauchoResponse getCauchoResponse()
797   {
798     return _response;
799   }
800   
801   /**
802    * Returns the servlet response for the page.
803    */

804   public HttpServletRequest JavaDoc getCauchoRequest()
805   {
806     return _request;
807   }
808
809   public HttpSession JavaDoc getSession()
810   {
811     if (_session == null)
812       _session = getCauchoRequest().getSession(false);
813     
814     return _session;
815   }
816
817   /**
818    * Returns the session, throwing an IllegalStateException if it's
819    * not available.
820    */

821   public HttpSession JavaDoc getSessionScope()
822   {
823     if (_session == null)
824       _session = getCauchoRequest().getSession(false);
825
826     if (_session == null)
827       throw new IllegalStateException JavaDoc(L.l("session is not available"));
828     
829     return _session;
830   }
831
832   public ServletConfig getServletConfig()
833   {
834     return _servlet.getServletConfig();
835   }
836
837   /**
838    * Returns the page's servlet context.
839    */

840   public ServletContext getServletContext()
841   {
842     return _webApp;
843   }
844
845   /**
846    * Returns the page's webApp.
847    */

848   public WebApp getApplication()
849   {
850     return _webApp;
851   }
852
853   /**
854    * Returns the page's error page.
855    */

856   public String JavaDoc getErrorPage()
857   {
858     return _errorPage;
859   }
860
861   /**
862    * Sets the page's error page.
863    */

864   public void setErrorPage(String JavaDoc errorPage)
865   {
866     _errorPage = errorPage;
867   }
868   
869   public Exception JavaDoc getException()
870   {
871     return (Exception JavaDoc) getThrowable();
872   }
873
874   /**
875    * Returns the Throwable stored by the error page.
876    */

877   public Throwable JavaDoc getThrowable()
878   {
879     Throwable JavaDoc exn = (Throwable JavaDoc) getCauchoRequest().getAttribute(EXCEPTION);
880     
881     if (exn == null)
882       exn = (Throwable JavaDoc) getCauchoRequest().getAttribute("javax.servlet.error.exception_type");
883     if (exn == null)
884       exn = (Throwable JavaDoc) getCauchoRequest().getAttribute("javax.servlet.jsp:jspException");
885     
886     return exn;
887   }
888
889   public void include(String JavaDoc relativeUrl)
890     throws ServletException, IOException JavaDoc
891   {
892     include(relativeUrl, false);
893   }
894   
895   /**
896    * Include another servlet into the current output stream.
897    *
898    * @param relativeUrl url relative to the current request.
899    */

900   public void include(String JavaDoc relativeUrl, String JavaDoc query, boolean flush)
901     throws ServletException, IOException JavaDoc
902   {
903     if ("".equals(query)) {
904     }
905     else if (relativeUrl.indexOf('?') > 0)
906       relativeUrl = relativeUrl + '&' + query;
907     else
908       relativeUrl = relativeUrl + '?' + query;
909
910     include(relativeUrl, flush);
911   }
912   
913   /**
914    * Include another servlet into the current output stream.
915    *
916    * @param relativeUrl url relative to the current request.
917    */

918   public void include(String JavaDoc relativeUrl, boolean flush)
919     throws ServletException, IOException JavaDoc
920   {
921     RequestDispatcher rd = null;
922
923     HttpServletRequest JavaDoc req = (HttpServletRequest JavaDoc) getCauchoRequest();
924     HttpServletResponse JavaDoc res = (HttpServletResponse JavaDoc) getResponse();
925
926     if (relativeUrl != null && ! relativeUrl.startsWith("/")) {
927       String JavaDoc path = RequestAdapter.getPageServletPath(req);
928       if (path == null)
929         path = RequestAdapter.getPagePathInfo(req);
930       if (path == null)
931         path = "/";
932       int p = path.lastIndexOf('/');
933       if (p >= 0) {
934     _cb.clear();
935     _cb.append(path, 0, p + 1);
936     _cb.append(relativeUrl);
937         rd = getServletContext().getRequestDispatcher(_cb.toString());
938       }
939     }
940
941     if (rd == null)
942       rd = req.getRequestDispatcher(relativeUrl);
943
944     if (rd == null)
945       throw new ServletException(L.l("unknown including page `{0}'.",
946                                      relativeUrl));
947
948     // the FlushBuffer needs to happen to deal with OpenSymphony (Bug#1710)
949
// jsp/17e9, 15lc, 15m4
950
if (! flush) {
951     }
952     else if (_out instanceof FlushBuffer)
953       ((FlushBuffer) _out).flushBuffer();
954     else if (flush)
955       _out.flush();
956
957     rd.include(req, res);
958   }
959   
960   /**
961    * Include another servlet into the current output stream.
962    *
963    * @param relativeUrl url relative to the current request.
964    */

965   public void forward(String JavaDoc relativeUrl, String JavaDoc query)
966     throws ServletException, IOException JavaDoc
967   {
968     if ("".equals(query)) {
969     }
970     else if (relativeUrl.indexOf('?') > 0)
971       relativeUrl = relativeUrl + '&' + query;
972  &nb