001    /**
002     *
003     * Copyright 2003-2004 The Apache Software Foundation
004     *
005     *  Licensed under the Apache License, Version 2.0 (the "License");
006     *  you may not use this file except in compliance with the License.
007     *  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    
018    //
019    // This source code implements specifications defined by the Java
020    // Community Process. In order to remain compliant with the specification
021    // DO NOT add / change / or delete method signatures!
022    //
023    
024    package javax.servlet.jsp;
025    
026    import java.io.IOException;
027    
028    import javax.servlet.Servlet;
029    import javax.servlet.ServletConfig;
030    import javax.servlet.ServletContext;
031    import javax.servlet.ServletException;
032    import javax.servlet.ServletRequest;
033    import javax.servlet.ServletResponse;
034    
035    import javax.servlet.http.HttpSession;
036    
037    import javax.servlet.jsp.tagext.BodyContent;
038    
039    /**
040     * <p>
041     * PageContext extends JspContext to provide useful context information for
042     * when JSP technology is used in a Servlet environment.
043     * <p>
044     * A PageContext instance provides access to all the namespaces associated
045     * with a JSP page, provides access to several page attributes, as well as
046     * a layer above the implementation details.  Implicit objects are added
047     * to the pageContext automatically.
048     *
049     * <p> The <code> PageContext </code> class is an abstract class, designed to be
050     * extended to provide implementation dependent implementations thereof, by
051     * conformant JSP engine runtime environments. A PageContext instance is 
052     * obtained by a JSP implementation class by calling the
053     * JspFactory.getPageContext() method, and is released by calling
054     * JspFactory.releasePageContext().
055     *
056     * <p> An example of how PageContext, JspFactory, and other classes can be
057     * used  within a JSP Page Implementation object is given elsewhere.
058     *
059     * <p>
060     * The PageContext provides a number of facilities to the page/component 
061     * author and page implementor, including:
062     * <ul>
063     * <li>a single API to manage the various scoped namespaces
064     * <li>a number of convenience API's to access various public objects
065     * <li>a mechanism to obtain the JspWriter for output
066     * <li>a mechanism to manage session usage by the page
067     * <li>a mechanism to expose page directive attributes to the scripting 
068     *     environment
069     * <li>mechanisms to forward or include the current request to other active 
070     *     components in the application
071     * <li>a mechanism to handle errorpage exception processing
072     * </ul>
073     *
074     * <p><B>Methods Intended for Container Generated Code</B>
075     * <p>Some methods are intended to be used by the code generated by the
076     * container, not by code written by JSP page authors, or JSP tag library 
077     * authors.
078     * <p>The methods supporting <B>lifecycle</B> are <code>initialize()</code>
079     * and <code>release()</code>
080     *
081     * <p>
082     * The following methods enable the <B>management of nested</B> JspWriter 
083     * streams to implement Tag Extensions: <code>pushBody()</code>
084     *
085     * <p><B>Methods Intended for JSP authors</B>
086     * <p>
087     * The following methods provide <B>convenient access</B> to implicit objects:
088     * <code>getException()</code>,  <code>getPage()</code>
089     * <code>getRequest()</code>,  <code>getResponse()</code>,
090     * <code>getSession()</code>,  <code>getServletConfig()</code>
091     * and <code>getServletContext()</code>.
092     *
093     * <p>
094     * The following methods provide support for <B>forwarding, inclusion
095     * and error handling</B>:
096     * <code>forward()</code>,  <code>include()</code>,
097     * and  <code>handlePageException()</code>.
098     */
099    
100    abstract public class PageContext 
101        extends JspContext
102    {
103        
104        /**
105         * Sole constructor. (For invocation by subclass constructors, 
106         * typically implicit.)
107         */
108        public PageContext() {
109        }
110        
111        /**
112         * Page scope: (this is the default) the named reference remains available
113         * in this PageContext until the return from the current Servlet.service()
114         * invocation.
115         */
116    
117        public static final int PAGE_SCOPE          = 1;
118    
119        /**
120         * Request scope: the named reference remains available from the 
121         * ServletRequest associated with the Servlet until the current request 
122         * is completed.
123         */
124    
125        public static final int REQUEST_SCOPE       = 2;
126    
127        /**
128         * Session scope (only valid if this page participates in a session):
129         * the named reference remains available from the HttpSession (if any)
130         * associated with the Servlet until the HttpSession is invalidated.
131         */
132    
133        public static final int SESSION_SCOPE       = 3;
134    
135        /**
136         * Application scope: named reference remains available in the 
137         * ServletContext until it is reclaimed.
138         */
139    
140        public static final int APPLICATION_SCOPE   = 4;
141    
142        /**
143         * Name used to store the Servlet in this PageContext's nametables.
144         */
145    
146        public static final String PAGE = "javax.servlet.jsp.jspPage";
147    
148        /**
149         * Name used to store this PageContext in it's own name table.
150         */
151    
152        public static final String PAGECONTEXT = "javax.servlet.jsp.jspPageContext";
153    
154        /**
155         * Name used to store ServletRequest in PageContext name table.
156         */
157    
158        public static final String REQUEST = "javax.servlet.jsp.jspRequest";
159    
160        /**
161         * Name used to store ServletResponse in PageContext name table.
162         */
163    
164        public static final String RESPONSE = "javax.servlet.jsp.jspResponse";
165    
166        /**
167         * Name used to store ServletConfig in PageContext name table.
168         */
169    
170        public static final String CONFIG = "javax.servlet.jsp.jspConfig";
171    
172        /**
173         * Name used to store HttpSession in PageContext name table.
174         */
175    
176        public static final String SESSION = "javax.servlet.jsp.jspSession";
177        /**
178         * Name used to store current JspWriter in PageContext name table.
179         */
180    
181        public static final String OUT = "javax.servlet.jsp.jspOut";
182    
183        /**
184         * Name used to store ServletContext in PageContext name table.
185         */
186    
187        public static final String APPLICATION = "javax.servlet.jsp.jspApplication";
188    
189        /**
190         * Name used to store uncaught exception in ServletRequest attribute 
191         * list and PageContext name table.
192         */
193    
194        public static final String EXCEPTION = "javax.servlet.jsp.jspException";
195    
196        /**
197         * <p>
198         * The initialize method is called to initialize an uninitialized PageContext
199         * so that it may be used by a JSP Implementation class to service an
200         * incoming request and response within it's _jspService() method.
201         *
202         * <p>
203         * This method is typically called from JspFactory.getPageContext() in
204         * order to initialize state.
205         *
206         * <p>
207         * This method is required to create an initial JspWriter, and associate
208         * the "out" name in page scope with this newly created object.
209         *
210         * <p>
211         * This method should not be used by page  or tag library authors.
212         *
213         * @param servlet The Servlet that is associated with this PageContext
214         * @param request The currently pending request for this Servlet
215         * @param response The currently pending response for this Servlet
216         * @param errorPageURL The value of the errorpage attribute from the page 
217         *     directive or null
218         * @param needsSession The value of the session attribute from the 
219         *     page directive
220         * @param bufferSize The value of the buffer attribute from the page 
221         *     directive
222         * @param autoFlush The value of the autoflush attribute from the page 
223         *     directive
224         *
225         * @throws IOException during creation of JspWriter
226         * @throws IllegalStateException if out not correctly initialized
227         * @throws IllegalArgumentException If one of the given parameters
228         *     is invalid
229         */
230     
231        abstract public void initialize(Servlet servlet, ServletRequest request, 
232            ServletResponse response, String errorPageURL, boolean needsSession, 
233            int bufferSize, boolean autoFlush)  
234            throws IOException, IllegalStateException, IllegalArgumentException;
235    
236        /**
237         * <p>
238         * This method shall "reset" the internal state of a PageContext, releasing
239         * all internal references, and preparing the PageContext for potential
240         * reuse by a later invocation of initialize(). This method is typically
241         * called from JspFactory.releasePageContext().
242         *
243         * <p>
244         * Subclasses shall envelope this method.
245         *
246         * <p>
247         * This method should not be used by page  or tag library authors.
248         *
249         */
250    
251        abstract public void release();
252    
253        /**
254         * The current value of the session object (an HttpSession).
255         *
256         * @return the HttpSession for this PageContext or null
257         */
258    
259        abstract public HttpSession getSession();
260    
261        /**
262         * The current value of the page object (In a Servlet environment, 
263         * this is an instance of javax.servlet.Servlet).
264         *
265         * @return the Page implementation class instance associated 
266         *     with this PageContext
267         */
268    
269        abstract public Object getPage();
270    
271    
272        /**
273         * The current value of the request object (a ServletRequest).
274         *
275         * @return The ServletRequest for this PageContext
276         */
277    
278        abstract public ServletRequest getRequest();
279    
280        /**
281         * The current value of the response object (a ServletResponse).
282         *
283         * @return the ServletResponse for this PageContext
284         */
285    
286        abstract public ServletResponse getResponse();
287    
288        /**
289         * The current value of the exception object (an Exception).
290         *
291         * @return any exception passed to this as an errorpage
292         */
293    
294        abstract public Exception getException();
295    
296        /**
297         * The ServletConfig instance.
298         *
299         * @return the ServletConfig for this PageContext
300         */
301    
302        abstract public ServletConfig getServletConfig();
303    
304        /**
305         * The ServletContext instance.
306         * 
307         * @return the ServletContext for this PageContext
308         */
309    
310        abstract public ServletContext getServletContext();
311    
312        /**
313         * <p>
314         * This method is used to re-direct, or "forward" the current 
315         * ServletRequest and ServletResponse to another active component in 
316         * the application.
317         * </p>
318         * <p>
319         * If the <I> relativeUrlPath </I> begins with a "/" then the URL specified
320         * is calculated relative to the DOCROOT of the <code> ServletContext </code>
321         * for this JSP. If the path does not begin with a "/" then the URL 
322         * specified is calculated relative to the URL of the request that was
323         * mapped to the calling JSP.
324         * </p>
325         * <p>
326         * It is only valid to call this method from a <code> Thread </code>
327         * executing within a <code> _jspService(...) </code> method of a JSP.
328         * </p>
329         * <p>
330         * Once this method has been called successfully, it is illegal for the
331         * calling <code> Thread </code> to attempt to modify the <code>
332         * ServletResponse </code> object.  Any such attempt to do so, shall result
333         * in undefined behavior. Typically, callers immediately return from 
334         * <code> _jspService(...) </code> after calling this method.
335         * </p>
336         *
337         * @param relativeUrlPath specifies the relative URL path to the target 
338         *     resource as described above
339         *
340         * @throws IllegalStateException if <code> ServletResponse </code> is not 
341         *     in a state where a forward can be performed
342         * @throws ServletException if the page that was forwarded to throws
343         *     a ServletException
344         * @throws IOException if an I/O error occurred while forwarding
345         */
346    
347        abstract public void forward(String relativeUrlPath) 
348            throws ServletException, IOException;
349    
350        /**
351         * <p>
352         * Causes the resource specified to be processed as part of the current
353         * ServletRequest and ServletResponse being processed by the calling Thread.
354         * The output of the target resources processing of the request is written
355         * directly to the ServletResponse output stream.
356         * </p>
357         * <p>
358         * The current JspWriter "out" for this JSP is flushed as a side-effect
359         * of this call, prior to processing the include.
360         * </p>
361         * <p>
362         * If the <I> relativeUrlPath </I> begins with a "/" then the URL specified
363         * is calculated relative to the DOCROOT of the <code>ServletContext</code>
364         * for this JSP. If the path does not begin with a "/" then the URL 
365         * specified is calculated relative to the URL of the request that was
366         * mapped to the calling JSP.
367         * </p>
368         * <p>
369         * It is only valid to call this method from a <code> Thread </code>
370         * executing within a <code> _jspService(...) </code> method of a JSP.
371         * </p>
372         *
373         * @param relativeUrlPath specifies the relative URL path to the target 
374         *     resource to be included
375         *
376         * @throws ServletException if the page that was forwarded to throws
377         *     a ServletException
378         * @throws IOException if an I/O error occurred while forwarding
379         */
380        abstract public void include(String relativeUrlPath) 
381            throws ServletException, IOException;
382    
383        /**
384         * <p>
385         * Causes the resource specified to be processed as part of the current
386         * ServletRequest and ServletResponse being processed by the calling Thread.
387         * The output of the target resources processing of the request is written
388         * directly to the current JspWriter returned by a call to getOut().
389         * </p>
390         * <p>
391         * If flush is true, The current JspWriter "out" for this JSP 
392         * is flushed as a side-effect of this call, prior to processing 
393         * the include.  Otherwise, the JspWriter "out" is not flushed.
394         * </p>
395         * <p>
396         * If the <i>relativeUrlPath</i> begins with a "/" then the URL specified
397         * is calculated relative to the DOCROOT of the <code>ServletContext</code>
398         * for this JSP. If the path does not begin with a "/" then the URL 
399         * specified is calculated relative to the URL of the request that was
400         * mapped to the calling JSP.
401         * </p>
402         * <p>
403         * It is only valid to call this method from a <code> Thread </code>
404         * executing within a <code> _jspService(...) </code> method of a JSP.
405         * </p>
406         *
407         * @param relativeUrlPath specifies the relative URL path to the 
408         *     target resource to be included
409         * @param flush True if the JspWriter is to be flushed before the include,
410         *     or false if not.
411         *
412         * @throws ServletException if the page that was forwarded to throws
413         *     a ServletException
414         * @throws IOException if an I/O error occurred while forwarding
415         * @since 2.0
416         */
417        abstract public void include(String relativeUrlPath, boolean flush) 
418            throws ServletException, IOException;
419    
420        /**
421         * <p>
422         * This method is intended to process an unhandled 'page' level
423         * exception by forwarding the exception to the specified
424         * error page for this JSP.  If forwarding is not possible (for
425         * example because the response has already been committed), an
426         * implementation dependent mechanism should be used to invoke
427         * the error page (e.g. "including" the error page instead).
428         *
429         * <p>
430         * If no error page is defined in the page, the exception should
431         * be rethrown so that the standard servlet error handling
432         * takes over.
433         *
434         * <p>
435         * A JSP implementation class shall typically clean up any local state
436         * prior to invoking this and will return immediately thereafter. It is
437         * illegal to generate any output to the client, or to modify any 
438         * ServletResponse state after invoking this call.
439         *
440         * <p>
441         * This method is kept for backwards compatiblity reasons.  Newly
442         * generated code should use PageContext.handlePageException(Throwable).
443         *
444         * @param e the exception to be handled
445         *
446         * @throws ServletException if an error occurs while invoking the error page
447         * @throws IOException if an I/O error occurred while invoking the error
448         *     page
449         * @throws NullPointerException if the exception is null
450         *
451         * @see #handlePageException(Throwable)
452         */
453    
454        abstract public void handlePageException(Exception e) 
455            throws ServletException, IOException;
456    
457        /**
458         * <p>
459         * This method is intended to process an unhandled 'page' level
460         * exception by forwarding the exception to the specified
461         * error page for this JSP.  If forwarding is not possible (for
462         * example because the response has already been committed), an
463         * implementation dependent mechanism should be used to invoke
464         * the error page (e.g. "including" the error page instead).
465         *
466         * <p>
467         * If no error page is defined in the page, the exception should
468         * be rethrown so that the standard servlet error handling
469         * takes over.
470         *
471         * <p>
472         * This method is intended to process an unhandled "page" level exception
473         * by redirecting the exception to either the specified error page for this
474         * JSP, or if none was specified, to perform some implementation dependent
475         * action.
476         *
477         * <p>
478         * A JSP implementation class shall typically clean up any local state
479         * prior to invoking this and will return immediately thereafter. It is
480         * illegal to generate any output to the client, or to modify any 
481         * ServletResponse state after invoking this call.
482         *
483         * @param t the throwable to be handled
484         *
485         * @throws ServletException if an error occurs while invoking the error page
486         * @throws IOException if an I/O error occurred while invoking the error
487         *     page
488         * @throws NullPointerException if the exception is null
489         *
490         * @see #handlePageException(Exception)
491         */
492    
493        abstract public void handlePageException(Throwable t) 
494            throws ServletException, IOException;
495    
496        /**
497         * Return a new BodyContent object, save the current "out" JspWriter,
498         * and update the value of the "out" attribute in the page scope
499         * attribute namespace of the PageContext.
500         *
501         * @return the new BodyContent
502         */
503    
504        public BodyContent pushBody() {
505            return null; // XXX to implement
506        }
507             
508    
509        /**
510         * Provides convenient access to error information.
511         *
512         * @return an ErrorData instance containing information about the 
513         * error, as obtained from the request attributes, as per the 
514         * Servlet specification.  If this is not an error page (that is,
515         * if the isErrorPage attribute of the page directive is not set
516         * to "true"), the information is meaningless.
517         *
518         * @since 2.0
519         */
520        public ErrorData getErrorData() {
521            return new ErrorData( 
522                (Throwable)getRequest().getAttribute( "javax.servlet.error.exception" ),
523                ((Integer)getRequest().getAttribute( 
524                    "javax.servlet.error.status_code" )).intValue(),
525                (String)getRequest().getAttribute( "javax.servlet.error.request_uri" ),
526                (String)getRequest().getAttribute( "javax.servlet.error.servlet_name" ) );
527        }
528        
529    }