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